##// END OF EJS Templates
rhg: parallellize computation of [unsure_is_modified]...
Arseniy Alekseyev -
r50412:52464a20 default
parent child Browse files
Show More
@@ -1,1276 +1,1277 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 "ouroboros",
471 "ouroboros",
472 "pretty_assertions",
472 "pretty_assertions",
473 "rand 0.8.5",
473 "rand 0.8.5",
474 "rand_distr",
474 "rand_distr",
475 "rand_pcg",
475 "rand_pcg",
476 "rayon",
476 "rayon",
477 "regex",
477 "regex",
478 "same-file",
478 "same-file",
479 "sha-1 0.10.0",
479 "sha-1 0.10.0",
480 "tempfile",
480 "tempfile",
481 "twox-hash",
481 "twox-hash",
482 "zstd",
482 "zstd",
483 ]
483 ]
484
484
485 [[package]]
485 [[package]]
486 name = "hg-cpython"
486 name = "hg-cpython"
487 version = "0.1.0"
487 version = "0.1.0"
488 dependencies = [
488 dependencies = [
489 "cpython",
489 "cpython",
490 "crossbeam-channel",
490 "crossbeam-channel",
491 "env_logger",
491 "env_logger",
492 "hg-core",
492 "hg-core",
493 "libc",
493 "libc",
494 "log",
494 "log",
495 "stable_deref_trait",
495 "stable_deref_trait",
496 "vcsgraph",
496 "vcsgraph",
497 ]
497 ]
498
498
499 [[package]]
499 [[package]]
500 name = "home"
500 name = "home"
501 version = "0.5.3"
501 version = "0.5.3"
502 source = "registry+https://github.com/rust-lang/crates.io-index"
502 source = "registry+https://github.com/rust-lang/crates.io-index"
503 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
503 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
504 dependencies = [
504 dependencies = [
505 "winapi",
505 "winapi",
506 ]
506 ]
507
507
508 [[package]]
508 [[package]]
509 name = "humantime"
509 name = "humantime"
510 version = "2.1.0"
510 version = "2.1.0"
511 source = "registry+https://github.com/rust-lang/crates.io-index"
511 source = "registry+https://github.com/rust-lang/crates.io-index"
512 checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
512 checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
513
513
514 [[package]]
514 [[package]]
515 name = "im-rc"
515 name = "im-rc"
516 version = "15.0.0"
516 version = "15.0.0"
517 source = "registry+https://github.com/rust-lang/crates.io-index"
517 source = "registry+https://github.com/rust-lang/crates.io-index"
518 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
518 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
519 dependencies = [
519 dependencies = [
520 "bitmaps",
520 "bitmaps",
521 "rand_core 0.5.1",
521 "rand_core 0.5.1",
522 "rand_xoshiro",
522 "rand_xoshiro",
523 "sized-chunks",
523 "sized-chunks",
524 "typenum",
524 "typenum",
525 "version_check",
525 "version_check",
526 ]
526 ]
527
527
528 [[package]]
528 [[package]]
529 name = "instant"
529 name = "instant"
530 version = "0.1.12"
530 version = "0.1.12"
531 source = "registry+https://github.com/rust-lang/crates.io-index"
531 source = "registry+https://github.com/rust-lang/crates.io-index"
532 checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
532 checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
533 dependencies = [
533 dependencies = [
534 "cfg-if 1.0.0",
534 "cfg-if 1.0.0",
535 ]
535 ]
536
536
537 [[package]]
537 [[package]]
538 name = "itertools"
538 name = "itertools"
539 version = "0.9.0"
539 version = "0.9.0"
540 source = "registry+https://github.com/rust-lang/crates.io-index"
540 source = "registry+https://github.com/rust-lang/crates.io-index"
541 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
541 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
542 dependencies = [
542 dependencies = [
543 "either",
543 "either",
544 ]
544 ]
545
545
546 [[package]]
546 [[package]]
547 name = "itertools"
547 name = "itertools"
548 version = "0.10.3"
548 version = "0.10.3"
549 source = "registry+https://github.com/rust-lang/crates.io-index"
549 source = "registry+https://github.com/rust-lang/crates.io-index"
550 checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
550 checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
551 dependencies = [
551 dependencies = [
552 "either",
552 "either",
553 ]
553 ]
554
554
555 [[package]]
555 [[package]]
556 name = "jobserver"
556 name = "jobserver"
557 version = "0.1.21"
557 version = "0.1.21"
558 source = "registry+https://github.com/rust-lang/crates.io-index"
558 source = "registry+https://github.com/rust-lang/crates.io-index"
559 checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
559 checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
560 dependencies = [
560 dependencies = [
561 "libc",
561 "libc",
562 ]
562 ]
563
563
564 [[package]]
564 [[package]]
565 name = "lazy_static"
565 name = "lazy_static"
566 version = "1.4.0"
566 version = "1.4.0"
567 source = "registry+https://github.com/rust-lang/crates.io-index"
567 source = "registry+https://github.com/rust-lang/crates.io-index"
568 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
568 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
569
569
570 [[package]]
570 [[package]]
571 name = "libc"
571 name = "libc"
572 version = "0.2.124"
572 version = "0.2.124"
573 source = "registry+https://github.com/rust-lang/crates.io-index"
573 source = "registry+https://github.com/rust-lang/crates.io-index"
574 checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
574 checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
575
575
576 [[package]]
576 [[package]]
577 name = "libm"
577 name = "libm"
578 version = "0.2.1"
578 version = "0.2.1"
579 source = "registry+https://github.com/rust-lang/crates.io-index"
579 source = "registry+https://github.com/rust-lang/crates.io-index"
580 checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
580 checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
581
581
582 [[package]]
582 [[package]]
583 name = "libz-sys"
583 name = "libz-sys"
584 version = "1.1.2"
584 version = "1.1.2"
585 source = "registry+https://github.com/rust-lang/crates.io-index"
585 source = "registry+https://github.com/rust-lang/crates.io-index"
586 checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
586 checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
587 dependencies = [
587 dependencies = [
588 "cc",
588 "cc",
589 "pkg-config",
589 "pkg-config",
590 "vcpkg",
590 "vcpkg",
591 ]
591 ]
592
592
593 [[package]]
593 [[package]]
594 name = "log"
594 name = "log"
595 version = "0.4.14"
595 version = "0.4.14"
596 source = "registry+https://github.com/rust-lang/crates.io-index"
596 source = "registry+https://github.com/rust-lang/crates.io-index"
597 checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
597 checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
598 dependencies = [
598 dependencies = [
599 "cfg-if 1.0.0",
599 "cfg-if 1.0.0",
600 ]
600 ]
601
601
602 [[package]]
602 [[package]]
603 name = "memchr"
603 name = "memchr"
604 version = "2.4.1"
604 version = "2.4.1"
605 source = "registry+https://github.com/rust-lang/crates.io-index"
605 source = "registry+https://github.com/rust-lang/crates.io-index"
606 checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
606 checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
607
607
608 [[package]]
608 [[package]]
609 name = "memmap2"
609 name = "memmap2"
610 version = "0.5.7"
610 version = "0.5.7"
611 source = "registry+https://github.com/rust-lang/crates.io-index"
611 source = "registry+https://github.com/rust-lang/crates.io-index"
612 checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
612 checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
613 dependencies = [
613 dependencies = [
614 "libc",
614 "libc",
615 "stable_deref_trait",
615 "stable_deref_trait",
616 ]
616 ]
617
617
618 [[package]]
618 [[package]]
619 name = "memoffset"
619 name = "memoffset"
620 version = "0.6.1"
620 version = "0.6.1"
621 source = "registry+https://github.com/rust-lang/crates.io-index"
621 source = "registry+https://github.com/rust-lang/crates.io-index"
622 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
622 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
623 dependencies = [
623 dependencies = [
624 "autocfg",
624 "autocfg",
625 ]
625 ]
626
626
627 [[package]]
627 [[package]]
628 name = "micro-timer"
628 name = "micro-timer"
629 version = "0.4.0"
629 version = "0.4.0"
630 source = "registry+https://github.com/rust-lang/crates.io-index"
630 source = "registry+https://github.com/rust-lang/crates.io-index"
631 checksum = "5de32cb59a062672560d6f0842c4aa7714727457b9fe2daf8987d995a176a405"
631 checksum = "5de32cb59a062672560d6f0842c4aa7714727457b9fe2daf8987d995a176a405"
632 dependencies = [
632 dependencies = [
633 "micro-timer-macros",
633 "micro-timer-macros",
634 "scopeguard",
634 "scopeguard",
635 ]
635 ]
636
636
637 [[package]]
637 [[package]]
638 name = "micro-timer-macros"
638 name = "micro-timer-macros"
639 version = "0.4.0"
639 version = "0.4.0"
640 source = "registry+https://github.com/rust-lang/crates.io-index"
640 source = "registry+https://github.com/rust-lang/crates.io-index"
641 checksum = "cee948b94700125b52dfb68dd17c19f6326696c1df57f92c05ee857463c93ba1"
641 checksum = "cee948b94700125b52dfb68dd17c19f6326696c1df57f92c05ee857463c93ba1"
642 dependencies = [
642 dependencies = [
643 "proc-macro2",
643 "proc-macro2",
644 "quote",
644 "quote",
645 "scopeguard",
645 "scopeguard",
646 "syn",
646 "syn",
647 ]
647 ]
648
648
649 [[package]]
649 [[package]]
650 name = "miniz_oxide"
650 name = "miniz_oxide"
651 version = "0.4.3"
651 version = "0.4.3"
652 source = "registry+https://github.com/rust-lang/crates.io-index"
652 source = "registry+https://github.com/rust-lang/crates.io-index"
653 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
653 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
654 dependencies = [
654 dependencies = [
655 "adler",
655 "adler",
656 "autocfg",
656 "autocfg",
657 ]
657 ]
658
658
659 [[package]]
659 [[package]]
660 name = "num-integer"
660 name = "num-integer"
661 version = "0.1.44"
661 version = "0.1.44"
662 source = "registry+https://github.com/rust-lang/crates.io-index"
662 source = "registry+https://github.com/rust-lang/crates.io-index"
663 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
663 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
664 dependencies = [
664 dependencies = [
665 "autocfg",
665 "autocfg",
666 "num-traits",
666 "num-traits",
667 ]
667 ]
668
668
669 [[package]]
669 [[package]]
670 name = "num-traits"
670 name = "num-traits"
671 version = "0.2.14"
671 version = "0.2.14"
672 source = "registry+https://github.com/rust-lang/crates.io-index"
672 source = "registry+https://github.com/rust-lang/crates.io-index"
673 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
673 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
674 dependencies = [
674 dependencies = [
675 "autocfg",
675 "autocfg",
676 "libm",
676 "libm",
677 ]
677 ]
678
678
679 [[package]]
679 [[package]]
680 name = "num_cpus"
680 name = "num_cpus"
681 version = "1.13.0"
681 version = "1.13.0"
682 source = "registry+https://github.com/rust-lang/crates.io-index"
682 source = "registry+https://github.com/rust-lang/crates.io-index"
683 checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
683 checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
684 dependencies = [
684 dependencies = [
685 "hermit-abi",
685 "hermit-abi",
686 "libc",
686 "libc",
687 ]
687 ]
688
688
689 [[package]]
689 [[package]]
690 name = "opaque-debug"
690 name = "opaque-debug"
691 version = "0.3.0"
691 version = "0.3.0"
692 source = "registry+https://github.com/rust-lang/crates.io-index"
692 source = "registry+https://github.com/rust-lang/crates.io-index"
693 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
693 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
694
694
695 [[package]]
695 [[package]]
696 name = "ouroboros"
696 name = "ouroboros"
697 version = "0.15.0"
697 version = "0.15.0"
698 source = "registry+https://github.com/rust-lang/crates.io-index"
698 source = "registry+https://github.com/rust-lang/crates.io-index"
699 checksum = "9f31a3b678685b150cba82b702dcdc5e155893f63610cf388d30cd988d4ca2bf"
699 checksum = "9f31a3b678685b150cba82b702dcdc5e155893f63610cf388d30cd988d4ca2bf"
700 dependencies = [
700 dependencies = [
701 "aliasable",
701 "aliasable",
702 "ouroboros_macro",
702 "ouroboros_macro",
703 "stable_deref_trait",
703 "stable_deref_trait",
704 ]
704 ]
705
705
706 [[package]]
706 [[package]]
707 name = "ouroboros_macro"
707 name = "ouroboros_macro"
708 version = "0.15.0"
708 version = "0.15.0"
709 source = "registry+https://github.com/rust-lang/crates.io-index"
709 source = "registry+https://github.com/rust-lang/crates.io-index"
710 checksum = "084fd65d5dd8b3772edccb5ffd1e4b7eba43897ecd0f9401e330e8c542959408"
710 checksum = "084fd65d5dd8b3772edccb5ffd1e4b7eba43897ecd0f9401e330e8c542959408"
711 dependencies = [
711 dependencies = [
712 "Inflector",
712 "Inflector",
713 "proc-macro-error",
713 "proc-macro-error",
714 "proc-macro2",
714 "proc-macro2",
715 "quote",
715 "quote",
716 "syn",
716 "syn",
717 ]
717 ]
718
718
719 [[package]]
719 [[package]]
720 name = "output_vt100"
720 name = "output_vt100"
721 version = "0.1.2"
721 version = "0.1.2"
722 source = "registry+https://github.com/rust-lang/crates.io-index"
722 source = "registry+https://github.com/rust-lang/crates.io-index"
723 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
723 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
724 dependencies = [
724 dependencies = [
725 "winapi",
725 "winapi",
726 ]
726 ]
727
727
728 [[package]]
728 [[package]]
729 name = "paste"
729 name = "paste"
730 version = "1.0.5"
730 version = "1.0.5"
731 source = "registry+https://github.com/rust-lang/crates.io-index"
731 source = "registry+https://github.com/rust-lang/crates.io-index"
732 checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
732 checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
733
733
734 [[package]]
734 [[package]]
735 name = "pkg-config"
735 name = "pkg-config"
736 version = "0.3.19"
736 version = "0.3.19"
737 source = "registry+https://github.com/rust-lang/crates.io-index"
737 source = "registry+https://github.com/rust-lang/crates.io-index"
738 checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
738 checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
739
739
740 [[package]]
740 [[package]]
741 name = "ppv-lite86"
741 name = "ppv-lite86"
742 version = "0.2.10"
742 version = "0.2.10"
743 source = "registry+https://github.com/rust-lang/crates.io-index"
743 source = "registry+https://github.com/rust-lang/crates.io-index"
744 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
744 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
745
745
746 [[package]]
746 [[package]]
747 name = "pretty_assertions"
747 name = "pretty_assertions"
748 version = "1.1.0"
748 version = "1.1.0"
749 source = "registry+https://github.com/rust-lang/crates.io-index"
749 source = "registry+https://github.com/rust-lang/crates.io-index"
750 checksum = "76d5b548b725018ab5496482b45cb8bef21e9fed1858a6d674e3a8a0f0bb5d50"
750 checksum = "76d5b548b725018ab5496482b45cb8bef21e9fed1858a6d674e3a8a0f0bb5d50"
751 dependencies = [
751 dependencies = [
752 "ansi_term",
752 "ansi_term",
753 "ctor",
753 "ctor",
754 "diff",
754 "diff",
755 "output_vt100",
755 "output_vt100",
756 ]
756 ]
757
757
758 [[package]]
758 [[package]]
759 name = "proc-macro-error"
759 name = "proc-macro-error"
760 version = "1.0.4"
760 version = "1.0.4"
761 source = "registry+https://github.com/rust-lang/crates.io-index"
761 source = "registry+https://github.com/rust-lang/crates.io-index"
762 checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
762 checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
763 dependencies = [
763 dependencies = [
764 "proc-macro-error-attr",
764 "proc-macro-error-attr",
765 "proc-macro2",
765 "proc-macro2",
766 "quote",
766 "quote",
767 "syn",
767 "syn",
768 "version_check",
768 "version_check",
769 ]
769 ]
770
770
771 [[package]]
771 [[package]]
772 name = "proc-macro-error-attr"
772 name = "proc-macro-error-attr"
773 version = "1.0.4"
773 version = "1.0.4"
774 source = "registry+https://github.com/rust-lang/crates.io-index"
774 source = "registry+https://github.com/rust-lang/crates.io-index"
775 checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
775 checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
776 dependencies = [
776 dependencies = [
777 "proc-macro2",
777 "proc-macro2",
778 "quote",
778 "quote",
779 "version_check",
779 "version_check",
780 ]
780 ]
781
781
782 [[package]]
782 [[package]]
783 name = "proc-macro2"
783 name = "proc-macro2"
784 version = "1.0.24"
784 version = "1.0.24"
785 source = "registry+https://github.com/rust-lang/crates.io-index"
785 source = "registry+https://github.com/rust-lang/crates.io-index"
786 checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
786 checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
787 dependencies = [
787 dependencies = [
788 "unicode-xid",
788 "unicode-xid",
789 ]
789 ]
790
790
791 [[package]]
791 [[package]]
792 name = "python3-sys"
792 name = "python3-sys"
793 version = "0.7.0"
793 version = "0.7.0"
794 source = "registry+https://github.com/rust-lang/crates.io-index"
794 source = "registry+https://github.com/rust-lang/crates.io-index"
795 checksum = "b18b32e64c103d5045f44644d7ddddd65336f7a0521f6fde673240a9ecceb77e"
795 checksum = "b18b32e64c103d5045f44644d7ddddd65336f7a0521f6fde673240a9ecceb77e"
796 dependencies = [
796 dependencies = [
797 "libc",
797 "libc",
798 "regex",
798 "regex",
799 ]
799 ]
800
800
801 [[package]]
801 [[package]]
802 name = "quote"
802 name = "quote"
803 version = "1.0.7"
803 version = "1.0.7"
804 source = "registry+https://github.com/rust-lang/crates.io-index"
804 source = "registry+https://github.com/rust-lang/crates.io-index"
805 checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
805 checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
806 dependencies = [
806 dependencies = [
807 "proc-macro2",
807 "proc-macro2",
808 ]
808 ]
809
809
810 [[package]]
810 [[package]]
811 name = "rand"
811 name = "rand"
812 version = "0.7.3"
812 version = "0.7.3"
813 source = "registry+https://github.com/rust-lang/crates.io-index"
813 source = "registry+https://github.com/rust-lang/crates.io-index"
814 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
814 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
815 dependencies = [
815 dependencies = [
816 "getrandom 0.1.15",
816 "getrandom 0.1.15",
817 "libc",
817 "libc",
818 "rand_chacha 0.2.2",
818 "rand_chacha 0.2.2",
819 "rand_core 0.5.1",
819 "rand_core 0.5.1",
820 "rand_hc",
820 "rand_hc",
821 ]
821 ]
822
822
823 [[package]]
823 [[package]]
824 name = "rand"
824 name = "rand"
825 version = "0.8.5"
825 version = "0.8.5"
826 source = "registry+https://github.com/rust-lang/crates.io-index"
826 source = "registry+https://github.com/rust-lang/crates.io-index"
827 checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
827 checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
828 dependencies = [
828 dependencies = [
829 "libc",
829 "libc",
830 "rand_chacha 0.3.1",
830 "rand_chacha 0.3.1",
831 "rand_core 0.6.3",
831 "rand_core 0.6.3",
832 ]
832 ]
833
833
834 [[package]]
834 [[package]]
835 name = "rand_chacha"
835 name = "rand_chacha"
836 version = "0.2.2"
836 version = "0.2.2"
837 source = "registry+https://github.com/rust-lang/crates.io-index"
837 source = "registry+https://github.com/rust-lang/crates.io-index"
838 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
838 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
839 dependencies = [
839 dependencies = [
840 "ppv-lite86",
840 "ppv-lite86",
841 "rand_core 0.5.1",
841 "rand_core 0.5.1",
842 ]
842 ]
843
843
844 [[package]]
844 [[package]]
845 name = "rand_chacha"
845 name = "rand_chacha"
846 version = "0.3.1"
846 version = "0.3.1"
847 source = "registry+https://github.com/rust-lang/crates.io-index"
847 source = "registry+https://github.com/rust-lang/crates.io-index"
848 checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
848 checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
849 dependencies = [
849 dependencies = [
850 "ppv-lite86",
850 "ppv-lite86",
851 "rand_core 0.6.3",
851 "rand_core 0.6.3",
852 ]
852 ]
853
853
854 [[package]]
854 [[package]]
855 name = "rand_core"
855 name = "rand_core"
856 version = "0.5.1"
856 version = "0.5.1"
857 source = "registry+https://github.com/rust-lang/crates.io-index"
857 source = "registry+https://github.com/rust-lang/crates.io-index"
858 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
858 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
859 dependencies = [
859 dependencies = [
860 "getrandom 0.1.15",
860 "getrandom 0.1.15",
861 ]
861 ]
862
862
863 [[package]]
863 [[package]]
864 name = "rand_core"
864 name = "rand_core"
865 version = "0.6.3"
865 version = "0.6.3"
866 source = "registry+https://github.com/rust-lang/crates.io-index"
866 source = "registry+https://github.com/rust-lang/crates.io-index"
867 checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
867 checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
868 dependencies = [
868 dependencies = [
869 "getrandom 0.2.4",
869 "getrandom 0.2.4",
870 ]
870 ]
871
871
872 [[package]]
872 [[package]]
873 name = "rand_distr"
873 name = "rand_distr"
874 version = "0.4.3"
874 version = "0.4.3"
875 source = "registry+https://github.com/rust-lang/crates.io-index"
875 source = "registry+https://github.com/rust-lang/crates.io-index"
876 checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
876 checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
877 dependencies = [
877 dependencies = [
878 "num-traits",
878 "num-traits",
879 "rand 0.8.5",
879 "rand 0.8.5",
880 ]
880 ]
881
881
882 [[package]]
882 [[package]]
883 name = "rand_hc"
883 name = "rand_hc"
884 version = "0.2.0"
884 version = "0.2.0"
885 source = "registry+https://github.com/rust-lang/crates.io-index"
885 source = "registry+https://github.com/rust-lang/crates.io-index"
886 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
886 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
887 dependencies = [
887 dependencies = [
888 "rand_core 0.5.1",
888 "rand_core 0.5.1",
889 ]
889 ]
890
890
891 [[package]]
891 [[package]]
892 name = "rand_pcg"
892 name = "rand_pcg"
893 version = "0.3.1"
893 version = "0.3.1"
894 source = "registry+https://github.com/rust-lang/crates.io-index"
894 source = "registry+https://github.com/rust-lang/crates.io-index"
895 checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e"
895 checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e"
896 dependencies = [
896 dependencies = [
897 "rand_core 0.6.3",
897 "rand_core 0.6.3",
898 ]
898 ]
899
899
900 [[package]]
900 [[package]]
901 name = "rand_xoshiro"
901 name = "rand_xoshiro"
902 version = "0.4.0"
902 version = "0.4.0"
903 source = "registry+https://github.com/rust-lang/crates.io-index"
903 source = "registry+https://github.com/rust-lang/crates.io-index"
904 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
904 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
905 dependencies = [
905 dependencies = [
906 "rand_core 0.5.1",
906 "rand_core 0.5.1",
907 ]
907 ]
908
908
909 [[package]]
909 [[package]]
910 name = "rayon"
910 name = "rayon"
911 version = "1.5.1"
911 version = "1.5.1"
912 source = "registry+https://github.com/rust-lang/crates.io-index"
912 source = "registry+https://github.com/rust-lang/crates.io-index"
913 checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
913 checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
914 dependencies = [
914 dependencies = [
915 "autocfg",
915 "autocfg",
916 "crossbeam-deque",
916 "crossbeam-deque",
917 "either",
917 "either",
918 "rayon-core",
918 "rayon-core",
919 ]
919 ]
920
920
921 [[package]]
921 [[package]]
922 name = "rayon-core"
922 name = "rayon-core"
923 version = "1.9.1"
923 version = "1.9.1"
924 source = "registry+https://github.com/rust-lang/crates.io-index"
924 source = "registry+https://github.com/rust-lang/crates.io-index"
925 checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
925 checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
926 dependencies = [
926 dependencies = [
927 "crossbeam-channel",
927 "crossbeam-channel",
928 "crossbeam-deque",
928 "crossbeam-deque",
929 "crossbeam-utils",
929 "crossbeam-utils",
930 "lazy_static",
930 "lazy_static",
931 "num_cpus",
931 "num_cpus",
932 ]
932 ]
933
933
934 [[package]]
934 [[package]]
935 name = "redox_syscall"
935 name = "redox_syscall"
936 version = "0.2.11"
936 version = "0.2.11"
937 source = "registry+https://github.com/rust-lang/crates.io-index"
937 source = "registry+https://github.com/rust-lang/crates.io-index"
938 checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
938 checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
939 dependencies = [
939 dependencies = [
940 "bitflags",
940 "bitflags",
941 ]
941 ]
942
942
943 [[package]]
943 [[package]]
944 name = "regex"
944 name = "regex"
945 version = "1.5.5"
945 version = "1.5.5"
946 source = "registry+https://github.com/rust-lang/crates.io-index"
946 source = "registry+https://github.com/rust-lang/crates.io-index"
947 checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
947 checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
948 dependencies = [
948 dependencies = [
949 "aho-corasick",
949 "aho-corasick",
950 "memchr",
950 "memchr",
951 "regex-syntax",
951 "regex-syntax",
952 ]
952 ]
953
953
954 [[package]]
954 [[package]]
955 name = "regex-syntax"
955 name = "regex-syntax"
956 version = "0.6.25"
956 version = "0.6.25"
957 source = "registry+https://github.com/rust-lang/crates.io-index"
957 source = "registry+https://github.com/rust-lang/crates.io-index"
958 checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
958 checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
959
959
960 [[package]]
960 [[package]]
961 name = "remove_dir_all"
961 name = "remove_dir_all"
962 version = "0.5.3"
962 version = "0.5.3"
963 source = "registry+https://github.com/rust-lang/crates.io-index"
963 source = "registry+https://github.com/rust-lang/crates.io-index"
964 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
964 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
965 dependencies = [
965 dependencies = [
966 "winapi",
966 "winapi",
967 ]
967 ]
968
968
969 [[package]]
969 [[package]]
970 name = "rhg"
970 name = "rhg"
971 version = "0.1.0"
971 version = "0.1.0"
972 dependencies = [
972 dependencies = [
973 "atty",
973 "atty",
974 "chrono",
974 "chrono",
975 "clap",
975 "clap",
976 "derive_more",
976 "derive_more",
977 "env_logger",
977 "env_logger",
978 "format-bytes",
978 "format-bytes",
979 "hg-core",
979 "hg-core",
980 "home",
980 "home",
981 "lazy_static",
981 "lazy_static",
982 "log",
982 "log",
983 "micro-timer",
983 "micro-timer",
984 "rayon",
984 "regex",
985 "regex",
985 "users",
986 "users",
986 "which",
987 "which",
987 ]
988 ]
988
989
989 [[package]]
990 [[package]]
990 name = "rustc_version"
991 name = "rustc_version"
991 version = "0.4.0"
992 version = "0.4.0"
992 source = "registry+https://github.com/rust-lang/crates.io-index"
993 source = "registry+https://github.com/rust-lang/crates.io-index"
993 checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
994 checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
994 dependencies = [
995 dependencies = [
995 "semver",
996 "semver",
996 ]
997 ]
997
998
998 [[package]]
999 [[package]]
999 name = "same-file"
1000 name = "same-file"
1000 version = "1.0.6"
1001 version = "1.0.6"
1001 source = "registry+https://github.com/rust-lang/crates.io-index"
1002 source = "registry+https://github.com/rust-lang/crates.io-index"
1002 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
1003 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
1003 dependencies = [
1004 dependencies = [
1004 "winapi-util",
1005 "winapi-util",
1005 ]
1006 ]
1006
1007
1007 [[package]]
1008 [[package]]
1008 name = "scopeguard"
1009 name = "scopeguard"
1009 version = "1.1.0"
1010 version = "1.1.0"
1010 source = "registry+https://github.com/rust-lang/crates.io-index"
1011 source = "registry+https://github.com/rust-lang/crates.io-index"
1011 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1012 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1012
1013
1013 [[package]]
1014 [[package]]
1014 name = "semver"
1015 name = "semver"
1015 version = "1.0.6"
1016 version = "1.0.6"
1016 source = "registry+https://github.com/rust-lang/crates.io-index"
1017 source = "registry+https://github.com/rust-lang/crates.io-index"
1017 checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
1018 checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
1018
1019
1019 [[package]]
1020 [[package]]
1020 name = "sha-1"
1021 name = "sha-1"
1021 version = "0.9.6"
1022 version = "0.9.6"
1022 source = "registry+https://github.com/rust-lang/crates.io-index"
1023 source = "registry+https://github.com/rust-lang/crates.io-index"
1023 checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
1024 checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
1024 dependencies = [
1025 dependencies = [
1025 "block-buffer 0.9.0",
1026 "block-buffer 0.9.0",
1026 "cfg-if 1.0.0",
1027 "cfg-if 1.0.0",
1027 "cpufeatures 0.1.4",
1028 "cpufeatures 0.1.4",
1028 "digest 0.9.0",
1029 "digest 0.9.0",
1029 "opaque-debug",
1030 "opaque-debug",
1030 ]
1031 ]
1031
1032
1032 [[package]]
1033 [[package]]
1033 name = "sha-1"
1034 name = "sha-1"
1034 version = "0.10.0"
1035 version = "0.10.0"
1035 source = "registry+https://github.com/rust-lang/crates.io-index"
1036 source = "registry+https://github.com/rust-lang/crates.io-index"
1036 checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
1037 checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
1037 dependencies = [
1038 dependencies = [
1038 "cfg-if 1.0.0",
1039 "cfg-if 1.0.0",
1039 "cpufeatures 0.2.1",
1040 "cpufeatures 0.2.1",
1040 "digest 0.10.2",
1041 "digest 0.10.2",
1041 ]
1042 ]
1042
1043
1043 [[package]]
1044 [[package]]
1044 name = "sized-chunks"
1045 name = "sized-chunks"
1045 version = "0.6.2"
1046 version = "0.6.2"
1046 source = "registry+https://github.com/rust-lang/crates.io-index"
1047 source = "registry+https://github.com/rust-lang/crates.io-index"
1047 checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
1048 checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
1048 dependencies = [
1049 dependencies = [
1049 "bitmaps",
1050 "bitmaps",
1050 "typenum",
1051 "typenum",
1051 ]
1052 ]
1052
1053
1053 [[package]]
1054 [[package]]
1054 name = "stable_deref_trait"
1055 name = "stable_deref_trait"
1055 version = "1.2.0"
1056 version = "1.2.0"
1056 source = "registry+https://github.com/rust-lang/crates.io-index"
1057 source = "registry+https://github.com/rust-lang/crates.io-index"
1057 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
1058 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
1058
1059
1059 [[package]]
1060 [[package]]
1060 name = "static_assertions"
1061 name = "static_assertions"
1061 version = "1.1.0"
1062 version = "1.1.0"
1062 source = "registry+https://github.com/rust-lang/crates.io-index"
1063 source = "registry+https://github.com/rust-lang/crates.io-index"
1063 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
1064 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
1064
1065
1065 [[package]]
1066 [[package]]
1066 name = "strsim"
1067 name = "strsim"
1067 version = "0.8.0"
1068 version = "0.8.0"
1068 source = "registry+https://github.com/rust-lang/crates.io-index"
1069 source = "registry+https://github.com/rust-lang/crates.io-index"
1069 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
1070 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
1070
1071
1071 [[package]]
1072 [[package]]
1072 name = "syn"
1073 name = "syn"
1073 version = "1.0.54"
1074 version = "1.0.54"
1074 source = "registry+https://github.com/rust-lang/crates.io-index"
1075 source = "registry+https://github.com/rust-lang/crates.io-index"
1075 checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
1076 checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
1076 dependencies = [
1077 dependencies = [
1077 "proc-macro2",
1078 "proc-macro2",
1078 "quote",
1079 "quote",
1079 "unicode-xid",
1080 "unicode-xid",
1080 ]
1081 ]
1081
1082
1082 [[package]]
1083 [[package]]
1083 name = "tempfile"
1084 name = "tempfile"
1084 version = "3.3.0"
1085 version = "3.3.0"
1085 source = "registry+https://github.com/rust-lang/crates.io-index"
1086 source = "registry+https://github.com/rust-lang/crates.io-index"
1086 checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
1087 checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
1087 dependencies = [
1088 dependencies = [
1088 "cfg-if 1.0.0",
1089 "cfg-if 1.0.0",
1089 "fastrand",
1090 "fastrand",
1090 "libc",
1091 "libc",
1091 "redox_syscall",
1092 "redox_syscall",
1092 "remove_dir_all",
1093 "remove_dir_all",
1093 "winapi",
1094 "winapi",
1094 ]
1095 ]
1095
1096
1096 [[package]]
1097 [[package]]
1097 name = "termcolor"
1098 name = "termcolor"
1098 version = "1.1.2"
1099 version = "1.1.2"
1099 source = "registry+https://github.com/rust-lang/crates.io-index"
1100 source = "registry+https://github.com/rust-lang/crates.io-index"
1100 checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
1101 checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
1101 dependencies = [
1102 dependencies = [
1102 "winapi-util",
1103 "winapi-util",
1103 ]
1104 ]
1104
1105
1105 [[package]]
1106 [[package]]
1106 name = "textwrap"
1107 name = "textwrap"
1107 version = "0.11.0"
1108 version = "0.11.0"
1108 source = "registry+https://github.com/rust-lang/crates.io-index"
1109 source = "registry+https://github.com/rust-lang/crates.io-index"
1109 checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
1110 checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
1110 dependencies = [
1111 dependencies = [
1111 "unicode-width",
1112 "unicode-width",
1112 ]
1113 ]
1113
1114
1114 [[package]]
1115 [[package]]
1115 name = "time"
1116 name = "time"
1116 version = "0.1.44"
1117 version = "0.1.44"
1117 source = "registry+https://github.com/rust-lang/crates.io-index"
1118 source = "registry+https://github.com/rust-lang/crates.io-index"
1118 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
1119 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
1119 dependencies = [
1120 dependencies = [
1120 "libc",
1121 "libc",
1121 "wasi 0.10.0+wasi-snapshot-preview1",
1122 "wasi 0.10.0+wasi-snapshot-preview1",
1122 "winapi",
1123 "winapi",
1123 ]
1124 ]
1124
1125
1125 [[package]]
1126 [[package]]
1126 name = "twox-hash"
1127 name = "twox-hash"
1127 version = "1.6.2"
1128 version = "1.6.2"
1128 source = "registry+https://github.com/rust-lang/crates.io-index"
1129 source = "registry+https://github.com/rust-lang/crates.io-index"
1129 checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0"
1130 checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0"
1130 dependencies = [
1131 dependencies = [
1131 "cfg-if 1.0.0",
1132 "cfg-if 1.0.0",
1132 "rand 0.8.5",
1133 "rand 0.8.5",
1133 "static_assertions",
1134 "static_assertions",
1134 ]
1135 ]
1135
1136
1136 [[package]]
1137 [[package]]
1137 name = "typenum"
1138 name = "typenum"
1138 version = "1.12.0"
1139 version = "1.12.0"
1139 source = "registry+https://github.com/rust-lang/crates.io-index"
1140 source = "registry+https://github.com/rust-lang/crates.io-index"
1140 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
1141 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
1141
1142
1142 [[package]]
1143 [[package]]
1143 name = "unicode-width"
1144 name = "unicode-width"
1144 version = "0.1.9"
1145 version = "0.1.9"
1145 source = "registry+https://github.com/rust-lang/crates.io-index"
1146 source = "registry+https://github.com/rust-lang/crates.io-index"
1146 checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
1147 checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
1147
1148
1148 [[package]]
1149 [[package]]
1149 name = "unicode-xid"
1150 name = "unicode-xid"
1150 version = "0.2.1"
1151 version = "0.2.1"
1151 source = "registry+https://github.com/rust-lang/crates.io-index"
1152 source = "registry+https://github.com/rust-lang/crates.io-index"
1152 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
1153 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
1153
1154
1154 [[package]]
1155 [[package]]
1155 name = "users"
1156 name = "users"
1156 version = "0.11.0"
1157 version = "0.11.0"
1157 source = "registry+https://github.com/rust-lang/crates.io-index"
1158 source = "registry+https://github.com/rust-lang/crates.io-index"
1158 checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
1159 checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
1159 dependencies = [
1160 dependencies = [
1160 "libc",
1161 "libc",
1161 "log",
1162 "log",
1162 ]
1163 ]
1163
1164
1164 [[package]]
1165 [[package]]
1165 name = "vcpkg"
1166 name = "vcpkg"
1166 version = "0.2.11"
1167 version = "0.2.11"
1167 source = "registry+https://github.com/rust-lang/crates.io-index"
1168 source = "registry+https://github.com/rust-lang/crates.io-index"
1168 checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
1169 checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
1169
1170
1170 [[package]]
1171 [[package]]
1171 name = "vcsgraph"
1172 name = "vcsgraph"
1172 version = "0.2.0"
1173 version = "0.2.0"
1173 source = "registry+https://github.com/rust-lang/crates.io-index"
1174 source = "registry+https://github.com/rust-lang/crates.io-index"
1174 checksum = "4cb68c231e2575f7503a7c19213875f9d4ec2e84e963a56ce3de4b6bee351ef7"
1175 checksum = "4cb68c231e2575f7503a7c19213875f9d4ec2e84e963a56ce3de4b6bee351ef7"
1175 dependencies = [
1176 dependencies = [
1176 "hex",
1177 "hex",
1177 "rand 0.7.3",
1178 "rand 0.7.3",
1178 "sha-1 0.9.6",
1179 "sha-1 0.9.6",
1179 ]
1180 ]
1180
1181
1181 [[package]]
1182 [[package]]
1182 name = "vec_map"
1183 name = "vec_map"
1183 version = "0.8.2"
1184 version = "0.8.2"
1184 source = "registry+https://github.com/rust-lang/crates.io-index"
1185 source = "registry+https://github.com/rust-lang/crates.io-index"
1185 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1186 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1186
1187
1187 [[package]]
1188 [[package]]
1188 name = "version_check"
1189 name = "version_check"
1189 version = "0.9.2"
1190 version = "0.9.2"
1190 source = "registry+https://github.com/rust-lang/crates.io-index"
1191 source = "registry+https://github.com/rust-lang/crates.io-index"
1191 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
1192 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
1192
1193
1193 [[package]]
1194 [[package]]
1194 name = "wasi"
1195 name = "wasi"
1195 version = "0.9.0+wasi-snapshot-preview1"
1196 version = "0.9.0+wasi-snapshot-preview1"
1196 source = "registry+https://github.com/rust-lang/crates.io-index"
1197 source = "registry+https://github.com/rust-lang/crates.io-index"
1197 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1198 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1198
1199
1199 [[package]]
1200 [[package]]
1200 name = "wasi"
1201 name = "wasi"
1201 version = "0.10.0+wasi-snapshot-preview1"
1202 version = "0.10.0+wasi-snapshot-preview1"
1202 source = "registry+https://github.com/rust-lang/crates.io-index"
1203 source = "registry+https://github.com/rust-lang/crates.io-index"
1203 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1204 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1204
1205
1205 [[package]]
1206 [[package]]
1206 name = "which"
1207 name = "which"
1207 version = "4.2.5"
1208 version = "4.2.5"
1208 source = "registry+https://github.com/rust-lang/crates.io-index"
1209 source = "registry+https://github.com/rust-lang/crates.io-index"
1209 checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
1210 checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
1210 dependencies = [
1211 dependencies = [
1211 "either",
1212 "either",
1212 "lazy_static",
1213 "lazy_static",
1213 "libc",
1214 "libc",
1214 ]
1215 ]
1215
1216
1216 [[package]]
1217 [[package]]
1217 name = "winapi"
1218 name = "winapi"
1218 version = "0.3.9"
1219 version = "0.3.9"
1219 source = "registry+https://github.com/rust-lang/crates.io-index"
1220 source = "registry+https://github.com/rust-lang/crates.io-index"
1220 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1221 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1221 dependencies = [
1222 dependencies = [
1222 "winapi-i686-pc-windows-gnu",
1223 "winapi-i686-pc-windows-gnu",
1223 "winapi-x86_64-pc-windows-gnu",
1224 "winapi-x86_64-pc-windows-gnu",
1224 ]
1225 ]
1225
1226
1226 [[package]]
1227 [[package]]
1227 name = "winapi-i686-pc-windows-gnu"
1228 name = "winapi-i686-pc-windows-gnu"
1228 version = "0.4.0"
1229 version = "0.4.0"
1229 source = "registry+https://github.com/rust-lang/crates.io-index"
1230 source = "registry+https://github.com/rust-lang/crates.io-index"
1230 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1231 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1231
1232
1232 [[package]]
1233 [[package]]
1233 name = "winapi-util"
1234 name = "winapi-util"
1234 version = "0.1.5"
1235 version = "0.1.5"
1235 source = "registry+https://github.com/rust-lang/crates.io-index"
1236 source = "registry+https://github.com/rust-lang/crates.io-index"
1236 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1237 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1237 dependencies = [
1238 dependencies = [
1238 "winapi",
1239 "winapi",
1239 ]
1240 ]
1240
1241
1241 [[package]]
1242 [[package]]
1242 name = "winapi-x86_64-pc-windows-gnu"
1243 name = "winapi-x86_64-pc-windows-gnu"
1243 version = "0.4.0"
1244 version = "0.4.0"
1244 source = "registry+https://github.com/rust-lang/crates.io-index"
1245 source = "registry+https://github.com/rust-lang/crates.io-index"
1245 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1246 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1246
1247
1247 [[package]]
1248 [[package]]
1248 name = "zstd"
1249 name = "zstd"
1249 version = "0.5.4+zstd.1.4.7"
1250 version = "0.5.4+zstd.1.4.7"
1250 source = "registry+https://github.com/rust-lang/crates.io-index"
1251 source = "registry+https://github.com/rust-lang/crates.io-index"
1251 checksum = "69996ebdb1ba8b1517f61387a883857818a66c8a295f487b1ffd8fd9d2c82910"
1252 checksum = "69996ebdb1ba8b1517f61387a883857818a66c8a295f487b1ffd8fd9d2c82910"
1252 dependencies = [
1253 dependencies = [
1253 "zstd-safe",
1254 "zstd-safe",
1254 ]
1255 ]
1255
1256
1256 [[package]]
1257 [[package]]
1257 name = "zstd-safe"
1258 name = "zstd-safe"
1258 version = "2.0.6+zstd.1.4.7"
1259 version = "2.0.6+zstd.1.4.7"
1259 source = "registry+https://github.com/rust-lang/crates.io-index"
1260 source = "registry+https://github.com/rust-lang/crates.io-index"
1260 checksum = "98aa931fb69ecee256d44589d19754e61851ae4769bf963b385119b1cc37a49e"
1261 checksum = "98aa931fb69ecee256d44589d19754e61851ae4769bf963b385119b1cc37a49e"
1261 dependencies = [
1262 dependencies = [
1262 "libc",
1263 "libc",
1263 "zstd-sys",
1264 "zstd-sys",
1264 ]
1265 ]
1265
1266
1266 [[package]]
1267 [[package]]
1267 name = "zstd-sys"
1268 name = "zstd-sys"
1268 version = "1.4.18+zstd.1.4.7"
1269 version = "1.4.18+zstd.1.4.7"
1269 source = "registry+https://github.com/rust-lang/crates.io-index"
1270 source = "registry+https://github.com/rust-lang/crates.io-index"
1270 checksum = "a1e6e8778706838f43f771d80d37787cb2fe06dafe89dd3aebaf6721b9eaec81"
1271 checksum = "a1e6e8778706838f43f771d80d37787cb2fe06dafe89dd3aebaf6721b9eaec81"
1271 dependencies = [
1272 dependencies = [
1272 "cc",
1273 "cc",
1273 "glob",
1274 "glob",
1274 "itertools 0.9.0",
1275 "itertools 0.9.0",
1275 "libc",
1276 "libc",
1276 ]
1277 ]
@@ -1,205 +1,208 b''
1 use crate::errors::HgError;
1 use crate::errors::HgError;
2 use crate::repo::Repo;
2 use crate::repo::Repo;
3 use crate::revlog::path_encode::path_encode;
3 use crate::revlog::path_encode::path_encode;
4 use crate::revlog::revlog::RevlogEntry;
4 use crate::revlog::revlog::RevlogEntry;
5 use crate::revlog::revlog::{Revlog, RevlogError};
5 use crate::revlog::revlog::{Revlog, RevlogError};
6 use crate::revlog::NodePrefix;
6 use crate::revlog::NodePrefix;
7 use crate::revlog::Revision;
7 use crate::revlog::Revision;
8 use crate::utils::files::get_path_from_bytes;
8 use crate::utils::files::get_path_from_bytes;
9 use crate::utils::hg_path::HgPath;
9 use crate::utils::hg_path::HgPath;
10 use crate::utils::SliceExt;
10 use crate::utils::SliceExt;
11 use std::path::PathBuf;
11 use std::path::PathBuf;
12
12
13 /// A specialized `Revlog` to work with file data logs.
13 /// A specialized `Revlog` to work with file data logs.
14 pub struct Filelog {
14 pub struct Filelog {
15 /// The generic `revlog` format.
15 /// The generic `revlog` format.
16 revlog: Revlog,
16 revlog: Revlog,
17 }
17 }
18
18
19 impl Filelog {
19 impl Filelog {
20 pub fn open(repo: &Repo, file_path: &HgPath) -> Result<Self, HgError> {
20 pub fn open_vfs(
21 store_vfs: &crate::vfs::Vfs<'_>,
22 file_path: &HgPath,
23 ) -> Result<Self, HgError> {
21 let index_path = store_path(file_path, b".i");
24 let index_path = store_path(file_path, b".i");
22 let data_path = store_path(file_path, b".d");
25 let data_path = store_path(file_path, b".d");
23 let revlog = Revlog::open(
26 let revlog =
24 &repo.store_vfs(),
27 Revlog::open(store_vfs, index_path, Some(&data_path), false)?;
25 index_path,
26 Some(&data_path),
27 false,
28 )?;
29 Ok(Self { revlog })
28 Ok(Self { revlog })
30 }
29 }
31
30
31 pub fn open(repo: &Repo, file_path: &HgPath) -> Result<Self, HgError> {
32 Self::open_vfs(&repo.store_vfs(), file_path)
33 }
34
32 /// The given node ID is that of the file as found in a filelog, not of a
35 /// The given node ID is that of the file as found in a filelog, not of a
33 /// changeset.
36 /// changeset.
34 pub fn data_for_node(
37 pub fn data_for_node(
35 &self,
38 &self,
36 file_node: impl Into<NodePrefix>,
39 file_node: impl Into<NodePrefix>,
37 ) -> Result<FilelogRevisionData, RevlogError> {
40 ) -> Result<FilelogRevisionData, RevlogError> {
38 let file_rev = self.revlog.rev_from_node(file_node.into())?;
41 let file_rev = self.revlog.rev_from_node(file_node.into())?;
39 self.data_for_rev(file_rev)
42 self.data_for_rev(file_rev)
40 }
43 }
41
44
42 /// The given revision is that of the file as found in a filelog, not of a
45 /// The given revision is that of the file as found in a filelog, not of a
43 /// changeset.
46 /// changeset.
44 pub fn data_for_rev(
47 pub fn data_for_rev(
45 &self,
48 &self,
46 file_rev: Revision,
49 file_rev: Revision,
47 ) -> Result<FilelogRevisionData, RevlogError> {
50 ) -> Result<FilelogRevisionData, RevlogError> {
48 let data: Vec<u8> = self.revlog.get_rev_data(file_rev)?.into_owned();
51 let data: Vec<u8> = self.revlog.get_rev_data(file_rev)?.into_owned();
49 Ok(FilelogRevisionData(data.into()))
52 Ok(FilelogRevisionData(data.into()))
50 }
53 }
51
54
52 /// The given node ID is that of the file as found in a filelog, not of a
55 /// The given node ID is that of the file as found in a filelog, not of a
53 /// changeset.
56 /// changeset.
54 pub fn entry_for_node(
57 pub fn entry_for_node(
55 &self,
58 &self,
56 file_node: impl Into<NodePrefix>,
59 file_node: impl Into<NodePrefix>,
57 ) -> Result<FilelogEntry, RevlogError> {
60 ) -> Result<FilelogEntry, RevlogError> {
58 let file_rev = self.revlog.rev_from_node(file_node.into())?;
61 let file_rev = self.revlog.rev_from_node(file_node.into())?;
59 self.entry_for_rev(file_rev)
62 self.entry_for_rev(file_rev)
60 }
63 }
61
64
62 /// The given revision is that of the file as found in a filelog, not of a
65 /// The given revision is that of the file as found in a filelog, not of a
63 /// changeset.
66 /// changeset.
64 pub fn entry_for_rev(
67 pub fn entry_for_rev(
65 &self,
68 &self,
66 file_rev: Revision,
69 file_rev: Revision,
67 ) -> Result<FilelogEntry, RevlogError> {
70 ) -> Result<FilelogEntry, RevlogError> {
68 Ok(FilelogEntry(self.revlog.get_entry(file_rev)?))
71 Ok(FilelogEntry(self.revlog.get_entry(file_rev)?))
69 }
72 }
70 }
73 }
71
74
72 fn store_path(hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
75 fn store_path(hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
73 let encoded_bytes =
76 let encoded_bytes =
74 path_encode(&[b"data/", hg_path.as_bytes(), suffix].concat());
77 path_encode(&[b"data/", hg_path.as_bytes(), suffix].concat());
75 get_path_from_bytes(&encoded_bytes).into()
78 get_path_from_bytes(&encoded_bytes).into()
76 }
79 }
77
80
78 pub struct FilelogEntry<'a>(RevlogEntry<'a>);
81 pub struct FilelogEntry<'a>(RevlogEntry<'a>);
79
82
80 impl FilelogEntry<'_> {
83 impl FilelogEntry<'_> {
81 /// `self.data()` can be expensive, with decompression and delta
84 /// `self.data()` can be expensive, with decompression and delta
82 /// resolution.
85 /// resolution.
83 ///
86 ///
84 /// *Without* paying this cost, based on revlog index information
87 /// *Without* paying this cost, based on revlog index information
85 /// including `RevlogEntry::uncompressed_len`:
88 /// including `RevlogEntry::uncompressed_len`:
86 ///
89 ///
87 /// * Returns `true` if the length that `self.data().file_data().len()`
90 /// * Returns `true` if the length that `self.data().file_data().len()`
88 /// would return is definitely **not equal** to `other_len`.
91 /// would return is definitely **not equal** to `other_len`.
89 /// * Returns `false` if available information is inconclusive.
92 /// * Returns `false` if available information is inconclusive.
90 pub fn file_data_len_not_equal_to(&self, other_len: u64) -> bool {
93 pub fn file_data_len_not_equal_to(&self, other_len: u64) -> bool {
91 // Relevant code that implement this behavior in Python code:
94 // Relevant code that implement this behavior in Python code:
92 // basefilectx.cmp, filelog.size, storageutil.filerevisioncopied,
95 // basefilectx.cmp, filelog.size, storageutil.filerevisioncopied,
93 // revlog.size, revlog.rawsize
96 // revlog.size, revlog.rawsize
94
97
95 // Let’s call `file_data_len` what would be returned by
98 // Let’s call `file_data_len` what would be returned by
96 // `self.data().file_data().len()`.
99 // `self.data().file_data().len()`.
97
100
98 if self.0.is_censored() {
101 if self.0.is_censored() {
99 let file_data_len = 0;
102 let file_data_len = 0;
100 return other_len != file_data_len;
103 return other_len != file_data_len;
101 }
104 }
102
105
103 if self.0.has_length_affecting_flag_processor() {
106 if self.0.has_length_affecting_flag_processor() {
104 // We can’t conclude anything about `file_data_len`.
107 // We can’t conclude anything about `file_data_len`.
105 return false;
108 return false;
106 }
109 }
107
110
108 // Revlog revisions (usually) have metadata for the size of
111 // Revlog revisions (usually) have metadata for the size of
109 // their data after decompression and delta resolution
112 // their data after decompression and delta resolution
110 // as would be returned by `Revlog::get_rev_data`.
113 // as would be returned by `Revlog::get_rev_data`.
111 //
114 //
112 // For filelogs this is the file’s contents preceded by an optional
115 // For filelogs this is the file’s contents preceded by an optional
113 // metadata block.
116 // metadata block.
114 let uncompressed_len = if let Some(l) = self.0.uncompressed_len() {
117 let uncompressed_len = if let Some(l) = self.0.uncompressed_len() {
115 l as u64
118 l as u64
116 } else {
119 } else {
117 // The field was set to -1, the actual uncompressed len is unknown.
120 // The field was set to -1, the actual uncompressed len is unknown.
118 // We need to decompress to say more.
121 // We need to decompress to say more.
119 return false;
122 return false;
120 };
123 };
121 // `uncompressed_len = file_data_len + optional_metadata_len`,
124 // `uncompressed_len = file_data_len + optional_metadata_len`,
122 // so `file_data_len <= uncompressed_len`.
125 // so `file_data_len <= uncompressed_len`.
123 if uncompressed_len < other_len {
126 if uncompressed_len < other_len {
124 // Transitively, `file_data_len < other_len`.
127 // Transitively, `file_data_len < other_len`.
125 // So `other_len != file_data_len` definitely.
128 // So `other_len != file_data_len` definitely.
126 return true;
129 return true;
127 }
130 }
128
131
129 if uncompressed_len == other_len + 4 {
132 if uncompressed_len == other_len + 4 {
130 // It’s possible that `file_data_len == other_len` with an empty
133 // It’s possible that `file_data_len == other_len` with an empty
131 // metadata block (2 start marker bytes + 2 end marker bytes).
134 // metadata block (2 start marker bytes + 2 end marker bytes).
132 // This happens when there wouldn’t otherwise be metadata, but
135 // This happens when there wouldn’t otherwise be metadata, but
133 // the first 2 bytes of file data happen to match a start marker
136 // the first 2 bytes of file data happen to match a start marker
134 // and would be ambiguous.
137 // and would be ambiguous.
135 return false;
138 return false;
136 }
139 }
137
140
138 if !self.0.has_p1() {
141 if !self.0.has_p1() {
139 // There may or may not be copy metadata, so we can’t deduce more
142 // There may or may not be copy metadata, so we can’t deduce more
140 // about `file_data_len` without computing file data.
143 // about `file_data_len` without computing file data.
141 return false;
144 return false;
142 }
145 }
143
146
144 // Filelog ancestry is not meaningful in the way changelog ancestry is.
147 // Filelog ancestry is not meaningful in the way changelog ancestry is.
145 // It only provides hints to delta generation.
148 // It only provides hints to delta generation.
146 // p1 and p2 are set to null when making a copy or rename since
149 // p1 and p2 are set to null when making a copy or rename since
147 // contents are likely unrelatedto what might have previously existed
150 // contents are likely unrelatedto what might have previously existed
148 // at the destination path.
151 // at the destination path.
149 //
152 //
150 // Conversely, since here p1 is non-null, there is no copy metadata.
153 // Conversely, since here p1 is non-null, there is no copy metadata.
151 // Note that this reasoning may be invalidated in the presence of
154 // Note that this reasoning may be invalidated in the presence of
152 // merges made by some previous versions of Mercurial that
155 // merges made by some previous versions of Mercurial that
153 // swapped p1 and p2. See <https://bz.mercurial-scm.org/show_bug.cgi?id=6528>
156 // swapped p1 and p2. See <https://bz.mercurial-scm.org/show_bug.cgi?id=6528>
154 // and `tests/test-issue6528.t`.
157 // and `tests/test-issue6528.t`.
155 //
158 //
156 // Since copy metadata is currently the only kind of metadata
159 // Since copy metadata is currently the only kind of metadata
157 // kept in revlog data of filelogs,
160 // kept in revlog data of filelogs,
158 // this `FilelogEntry` does not have such metadata:
161 // this `FilelogEntry` does not have such metadata:
159 let file_data_len = uncompressed_len;
162 let file_data_len = uncompressed_len;
160
163
161 return file_data_len != other_len;
164 return file_data_len != other_len;
162 }
165 }
163
166
164 pub fn data(&self) -> Result<FilelogRevisionData, HgError> {
167 pub fn data(&self) -> Result<FilelogRevisionData, HgError> {
165 Ok(FilelogRevisionData(self.0.data()?.into_owned()))
168 Ok(FilelogRevisionData(self.0.data()?.into_owned()))
166 }
169 }
167 }
170 }
168
171
169 /// The data for one revision in a filelog, uncompressed and delta-resolved.
172 /// The data for one revision in a filelog, uncompressed and delta-resolved.
170 pub struct FilelogRevisionData(Vec<u8>);
173 pub struct FilelogRevisionData(Vec<u8>);
171
174
172 impl FilelogRevisionData {
175 impl FilelogRevisionData {
173 /// Split into metadata and data
176 /// Split into metadata and data
174 pub fn split(&self) -> Result<(Option<&[u8]>, &[u8]), HgError> {
177 pub fn split(&self) -> Result<(Option<&[u8]>, &[u8]), HgError> {
175 const DELIMITER: &[u8; 2] = &[b'\x01', b'\n'];
178 const DELIMITER: &[u8; 2] = &[b'\x01', b'\n'];
176
179
177 if let Some(rest) = self.0.drop_prefix(DELIMITER) {
180 if let Some(rest) = self.0.drop_prefix(DELIMITER) {
178 if let Some((metadata, data)) = rest.split_2_by_slice(DELIMITER) {
181 if let Some((metadata, data)) = rest.split_2_by_slice(DELIMITER) {
179 Ok((Some(metadata), data))
182 Ok((Some(metadata), data))
180 } else {
183 } else {
181 Err(HgError::corrupted(
184 Err(HgError::corrupted(
182 "Missing metadata end delimiter in filelog entry",
185 "Missing metadata end delimiter in filelog entry",
183 ))
186 ))
184 }
187 }
185 } else {
188 } else {
186 Ok((None, &self.0))
189 Ok((None, &self.0))
187 }
190 }
188 }
191 }
189
192
190 /// Returns the file contents at this revision, stripped of any metadata
193 /// Returns the file contents at this revision, stripped of any metadata
191 pub fn file_data(&self) -> Result<&[u8], HgError> {
194 pub fn file_data(&self) -> Result<&[u8], HgError> {
192 let (_metadata, data) = self.split()?;
195 let (_metadata, data) = self.split()?;
193 Ok(data)
196 Ok(data)
194 }
197 }
195
198
196 /// Consume the entry, and convert it into data, discarding any metadata,
199 /// Consume the entry, and convert it into data, discarding any metadata,
197 /// if present.
200 /// if present.
198 pub fn into_file_data(self) -> Result<Vec<u8>, HgError> {
201 pub fn into_file_data(self) -> Result<Vec<u8>, HgError> {
199 if let (Some(_metadata), data) = self.split()? {
202 if let (Some(_metadata), data) = self.split()? {
200 Ok(data.to_owned())
203 Ok(data.to_owned())
201 } else {
204 } else {
202 Ok(self.0)
205 Ok(self.0)
203 }
206 }
204 }
207 }
205 }
208 }
@@ -1,338 +1,338 b''
1 use std::{collections::HashSet, path::Path};
1 use std::{collections::HashSet, path::Path};
2
2
3 use format_bytes::{write_bytes, DisplayBytes};
3 use format_bytes::{write_bytes, DisplayBytes};
4
4
5 use crate::{
5 use crate::{
6 errors::HgError,
6 errors::HgError,
7 filepatterns::parse_pattern_file_contents,
7 filepatterns::parse_pattern_file_contents,
8 matchers::{
8 matchers::{
9 AlwaysMatcher, DifferenceMatcher, IncludeMatcher, Matcher,
9 AlwaysMatcher, DifferenceMatcher, IncludeMatcher, Matcher,
10 UnionMatcher,
10 UnionMatcher,
11 },
11 },
12 operations::cat,
12 operations::cat,
13 repo::Repo,
13 repo::Repo,
14 requirements::SPARSE_REQUIREMENT,
14 requirements::SPARSE_REQUIREMENT,
15 utils::{hg_path::HgPath, SliceExt},
15 utils::{hg_path::HgPath, SliceExt},
16 IgnorePattern, PatternError, PatternFileWarning, PatternSyntax, Revision,
16 IgnorePattern, PatternError, PatternFileWarning, PatternSyntax, Revision,
17 NULL_REVISION,
17 NULL_REVISION,
18 };
18 };
19
19
20 /// Command which is triggering the config read
20 /// Command which is triggering the config read
21 #[derive(Copy, Clone, Debug)]
21 #[derive(Copy, Clone, Debug)]
22 pub enum SparseConfigContext {
22 pub enum SparseConfigContext {
23 Sparse,
23 Sparse,
24 Narrow,
24 Narrow,
25 }
25 }
26
26
27 impl DisplayBytes for SparseConfigContext {
27 impl DisplayBytes for SparseConfigContext {
28 fn display_bytes(
28 fn display_bytes(
29 &self,
29 &self,
30 output: &mut dyn std::io::Write,
30 output: &mut dyn std::io::Write,
31 ) -> std::io::Result<()> {
31 ) -> std::io::Result<()> {
32 match self {
32 match self {
33 SparseConfigContext::Sparse => write_bytes!(output, b"sparse"),
33 SparseConfigContext::Sparse => write_bytes!(output, b"sparse"),
34 SparseConfigContext::Narrow => write_bytes!(output, b"narrow"),
34 SparseConfigContext::Narrow => write_bytes!(output, b"narrow"),
35 }
35 }
36 }
36 }
37 }
37 }
38
38
39 /// Possible warnings when reading sparse configuration
39 /// Possible warnings when reading sparse configuration
40 #[derive(Debug, derive_more::From)]
40 #[derive(Debug, derive_more::From)]
41 pub enum SparseWarning {
41 pub enum SparseWarning {
42 /// Warns about improper paths that start with "/"
42 /// Warns about improper paths that start with "/"
43 RootWarning {
43 RootWarning {
44 context: SparseConfigContext,
44 context: SparseConfigContext,
45 line: Vec<u8>,
45 line: Vec<u8>,
46 },
46 },
47 /// Warns about a profile missing from the given changelog revision
47 /// Warns about a profile missing from the given changelog revision
48 ProfileNotFound { profile: Vec<u8>, rev: Revision },
48 ProfileNotFound { profile: Vec<u8>, rev: Revision },
49 #[from]
49 #[from]
50 Pattern(PatternFileWarning),
50 Pattern(PatternFileWarning),
51 }
51 }
52
52
53 /// Parsed sparse config
53 /// Parsed sparse config
54 #[derive(Debug, Default)]
54 #[derive(Debug, Default)]
55 pub struct SparseConfig {
55 pub struct SparseConfig {
56 // Line-separated
56 // Line-separated
57 pub(crate) includes: Vec<u8>,
57 pub(crate) includes: Vec<u8>,
58 // Line-separated
58 // Line-separated
59 pub(crate) excludes: Vec<u8>,
59 pub(crate) excludes: Vec<u8>,
60 pub(crate) profiles: HashSet<Vec<u8>>,
60 pub(crate) profiles: HashSet<Vec<u8>>,
61 pub(crate) warnings: Vec<SparseWarning>,
61 pub(crate) warnings: Vec<SparseWarning>,
62 }
62 }
63
63
64 /// All possible errors when reading sparse/narrow config
64 /// All possible errors when reading sparse/narrow config
65 #[derive(Debug, derive_more::From)]
65 #[derive(Debug, derive_more::From)]
66 pub enum SparseConfigError {
66 pub enum SparseConfigError {
67 IncludesAfterExcludes {
67 IncludesAfterExcludes {
68 context: SparseConfigContext,
68 context: SparseConfigContext,
69 },
69 },
70 EntryOutsideSection {
70 EntryOutsideSection {
71 context: SparseConfigContext,
71 context: SparseConfigContext,
72 line: Vec<u8>,
72 line: Vec<u8>,
73 },
73 },
74 /// Narrow config does not support '%include' directives
74 /// Narrow config does not support '%include' directives
75 IncludesInNarrow,
75 IncludesInNarrow,
76 /// An invalid pattern prefix was given to the narrow spec. Includes the
76 /// An invalid pattern prefix was given to the narrow spec. Includes the
77 /// entire pattern for context.
77 /// entire pattern for context.
78 InvalidNarrowPrefix(Vec<u8>),
78 InvalidNarrowPrefix(Vec<u8>),
79 #[from]
79 #[from]
80 HgError(HgError),
80 HgError(HgError),
81 #[from]
81 #[from]
82 PatternError(PatternError),
82 PatternError(PatternError),
83 }
83 }
84
84
85 /// Parse sparse config file content.
85 /// Parse sparse config file content.
86 pub(crate) fn parse_config(
86 pub(crate) fn parse_config(
87 raw: &[u8],
87 raw: &[u8],
88 context: SparseConfigContext,
88 context: SparseConfigContext,
89 ) -> Result<SparseConfig, SparseConfigError> {
89 ) -> Result<SparseConfig, SparseConfigError> {
90 let mut includes = vec![];
90 let mut includes = vec![];
91 let mut excludes = vec![];
91 let mut excludes = vec![];
92 let mut profiles = HashSet::new();
92 let mut profiles = HashSet::new();
93 let mut warnings = vec![];
93 let mut warnings = vec![];
94
94
95 #[derive(PartialEq, Eq)]
95 #[derive(PartialEq, Eq)]
96 enum Current {
96 enum Current {
97 Includes,
97 Includes,
98 Excludes,
98 Excludes,
99 None,
99 None,
100 };
100 }
101
101
102 let mut current = Current::None;
102 let mut current = Current::None;
103 let mut in_section = false;
103 let mut in_section = false;
104
104
105 for line in raw.split(|c| *c == b'\n') {
105 for line in raw.split(|c| *c == b'\n') {
106 let line = line.trim();
106 let line = line.trim();
107 if line.is_empty() || line[0] == b'#' {
107 if line.is_empty() || line[0] == b'#' {
108 // empty or comment line, skip
108 // empty or comment line, skip
109 continue;
109 continue;
110 }
110 }
111 if line.starts_with(b"%include ") {
111 if line.starts_with(b"%include ") {
112 let profile = line[b"%include ".len()..].trim();
112 let profile = line[b"%include ".len()..].trim();
113 if !profile.is_empty() {
113 if !profile.is_empty() {
114 profiles.insert(profile.into());
114 profiles.insert(profile.into());
115 }
115 }
116 } else if line == b"[include]" {
116 } else if line == b"[include]" {
117 if in_section && current == Current::Includes {
117 if in_section && current == Current::Includes {
118 return Err(SparseConfigError::IncludesAfterExcludes {
118 return Err(SparseConfigError::IncludesAfterExcludes {
119 context,
119 context,
120 });
120 });
121 }
121 }
122 in_section = true;
122 in_section = true;
123 current = Current::Includes;
123 current = Current::Includes;
124 continue;
124 continue;
125 } else if line == b"[exclude]" {
125 } else if line == b"[exclude]" {
126 in_section = true;
126 in_section = true;
127 current = Current::Excludes;
127 current = Current::Excludes;
128 } else {
128 } else {
129 if current == Current::None {
129 if current == Current::None {
130 return Err(SparseConfigError::EntryOutsideSection {
130 return Err(SparseConfigError::EntryOutsideSection {
131 context,
131 context,
132 line: line.into(),
132 line: line.into(),
133 });
133 });
134 }
134 }
135 if line.trim().starts_with(b"/") {
135 if line.trim().starts_with(b"/") {
136 warnings.push(SparseWarning::RootWarning {
136 warnings.push(SparseWarning::RootWarning {
137 context,
137 context,
138 line: line.into(),
138 line: line.into(),
139 });
139 });
140 continue;
140 continue;
141 }
141 }
142 match current {
142 match current {
143 Current::Includes => {
143 Current::Includes => {
144 includes.push(b'\n');
144 includes.push(b'\n');
145 includes.extend(line.iter());
145 includes.extend(line.iter());
146 }
146 }
147 Current::Excludes => {
147 Current::Excludes => {
148 excludes.push(b'\n');
148 excludes.push(b'\n');
149 excludes.extend(line.iter());
149 excludes.extend(line.iter());
150 }
150 }
151 Current::None => unreachable!(),
151 Current::None => unreachable!(),
152 }
152 }
153 }
153 }
154 }
154 }
155
155
156 Ok(SparseConfig {
156 Ok(SparseConfig {
157 includes,
157 includes,
158 excludes,
158 excludes,
159 profiles,
159 profiles,
160 warnings,
160 warnings,
161 })
161 })
162 }
162 }
163
163
164 fn read_temporary_includes(
164 fn read_temporary_includes(
165 repo: &Repo,
165 repo: &Repo,
166 ) -> Result<Vec<Vec<u8>>, SparseConfigError> {
166 ) -> Result<Vec<Vec<u8>>, SparseConfigError> {
167 let raw = repo.hg_vfs().try_read("tempsparse")?.unwrap_or(vec![]);
167 let raw = repo.hg_vfs().try_read("tempsparse")?.unwrap_or(vec![]);
168 if raw.is_empty() {
168 if raw.is_empty() {
169 return Ok(vec![]);
169 return Ok(vec![]);
170 }
170 }
171 Ok(raw.split(|c| *c == b'\n').map(ToOwned::to_owned).collect())
171 Ok(raw.split(|c| *c == b'\n').map(ToOwned::to_owned).collect())
172 }
172 }
173
173
174 /// Obtain sparse checkout patterns for the given revision
174 /// Obtain sparse checkout patterns for the given revision
175 fn patterns_for_rev(
175 fn patterns_for_rev(
176 repo: &Repo,
176 repo: &Repo,
177 rev: Revision,
177 rev: Revision,
178 ) -> Result<Option<SparseConfig>, SparseConfigError> {
178 ) -> Result<Option<SparseConfig>, SparseConfigError> {
179 if !repo.has_sparse() {
179 if !repo.has_sparse() {
180 return Ok(None);
180 return Ok(None);
181 }
181 }
182 let raw = repo.hg_vfs().try_read("sparse")?.unwrap_or(vec![]);
182 let raw = repo.hg_vfs().try_read("sparse")?.unwrap_or(vec![]);
183
183
184 if raw.is_empty() {
184 if raw.is_empty() {
185 return Ok(None);
185 return Ok(None);
186 }
186 }
187
187
188 let mut config = parse_config(&raw, SparseConfigContext::Sparse)?;
188 let mut config = parse_config(&raw, SparseConfigContext::Sparse)?;
189
189
190 if !config.profiles.is_empty() {
190 if !config.profiles.is_empty() {
191 let mut profiles: Vec<Vec<u8>> = config.profiles.into_iter().collect();
191 let mut profiles: Vec<Vec<u8>> = config.profiles.into_iter().collect();
192 let mut visited = HashSet::new();
192 let mut visited = HashSet::new();
193
193
194 while let Some(profile) = profiles.pop() {
194 while let Some(profile) = profiles.pop() {
195 if visited.contains(&profile) {
195 if visited.contains(&profile) {
196 continue;
196 continue;
197 }
197 }
198 visited.insert(profile.to_owned());
198 visited.insert(profile.to_owned());
199
199
200 let output =
200 let output =
201 cat(repo, &rev.to_string(), vec![HgPath::new(&profile)])
201 cat(repo, &rev.to_string(), vec![HgPath::new(&profile)])
202 .map_err(|_| {
202 .map_err(|_| {
203 HgError::corrupted(format!(
203 HgError::corrupted(format!(
204 "dirstate points to non-existent parent node"
204 "dirstate points to non-existent parent node"
205 ))
205 ))
206 })?;
206 })?;
207 if output.results.is_empty() {
207 if output.results.is_empty() {
208 config.warnings.push(SparseWarning::ProfileNotFound {
208 config.warnings.push(SparseWarning::ProfileNotFound {
209 profile: profile.to_owned(),
209 profile: profile.to_owned(),
210 rev,
210 rev,
211 })
211 })
212 }
212 }
213
213
214 let subconfig = parse_config(
214 let subconfig = parse_config(
215 &output.results[0].1,
215 &output.results[0].1,
216 SparseConfigContext::Sparse,
216 SparseConfigContext::Sparse,
217 )?;
217 )?;
218 if !subconfig.includes.is_empty() {
218 if !subconfig.includes.is_empty() {
219 config.includes.push(b'\n');
219 config.includes.push(b'\n');
220 config.includes.extend(&subconfig.includes);
220 config.includes.extend(&subconfig.includes);
221 }
221 }
222 if !subconfig.includes.is_empty() {
222 if !subconfig.includes.is_empty() {
223 config.includes.push(b'\n');
223 config.includes.push(b'\n');
224 config.excludes.extend(&subconfig.excludes);
224 config.excludes.extend(&subconfig.excludes);
225 }
225 }
226 config.warnings.extend(subconfig.warnings.into_iter());
226 config.warnings.extend(subconfig.warnings.into_iter());
227 profiles.extend(subconfig.profiles.into_iter());
227 profiles.extend(subconfig.profiles.into_iter());
228 }
228 }
229
229
230 config.profiles = visited;
230 config.profiles = visited;
231 }
231 }
232
232
233 if !config.includes.is_empty() {
233 if !config.includes.is_empty() {
234 config.includes.extend(b"\n.hg*");
234 config.includes.extend(b"\n.hg*");
235 }
235 }
236
236
237 Ok(Some(config))
237 Ok(Some(config))
238 }
238 }
239
239
240 /// Obtain a matcher for sparse working directories.
240 /// Obtain a matcher for sparse working directories.
241 pub fn matcher(
241 pub fn matcher(
242 repo: &Repo,
242 repo: &Repo,
243 ) -> Result<(Box<dyn Matcher + Sync>, Vec<SparseWarning>), SparseConfigError> {
243 ) -> Result<(Box<dyn Matcher + Sync>, Vec<SparseWarning>), SparseConfigError> {
244 let mut warnings = vec![];
244 let mut warnings = vec![];
245 if !repo.requirements().contains(SPARSE_REQUIREMENT) {
245 if !repo.requirements().contains(SPARSE_REQUIREMENT) {
246 return Ok((Box::new(AlwaysMatcher), warnings));
246 return Ok((Box::new(AlwaysMatcher), warnings));
247 }
247 }
248
248
249 let parents = repo.dirstate_parents()?;
249 let parents = repo.dirstate_parents()?;
250 let mut revs = vec![];
250 let mut revs = vec![];
251 let p1_rev =
251 let p1_rev =
252 repo.changelog()?
252 repo.changelog()?
253 .rev_from_node(parents.p1.into())
253 .rev_from_node(parents.p1.into())
254 .map_err(|_| {
254 .map_err(|_| {
255 HgError::corrupted(format!(
255 HgError::corrupted(format!(
256 "dirstate points to non-existent parent node"
256 "dirstate points to non-existent parent node"
257 ))
257 ))
258 })?;
258 })?;
259 if p1_rev != NULL_REVISION {
259 if p1_rev != NULL_REVISION {
260 revs.push(p1_rev)
260 revs.push(p1_rev)
261 }
261 }
262 let p2_rev =
262 let p2_rev =
263 repo.changelog()?
263 repo.changelog()?
264 .rev_from_node(parents.p2.into())
264 .rev_from_node(parents.p2.into())
265 .map_err(|_| {
265 .map_err(|_| {
266 HgError::corrupted(format!(
266 HgError::corrupted(format!(
267 "dirstate points to non-existent parent node"
267 "dirstate points to non-existent parent node"
268 ))
268 ))
269 })?;
269 })?;
270 if p2_rev != NULL_REVISION {
270 if p2_rev != NULL_REVISION {
271 revs.push(p2_rev)
271 revs.push(p2_rev)
272 }
272 }
273 let mut matchers = vec![];
273 let mut matchers = vec![];
274
274
275 for rev in revs.iter() {
275 for rev in revs.iter() {
276 let config = patterns_for_rev(repo, *rev);
276 let config = patterns_for_rev(repo, *rev);
277 if let Ok(Some(config)) = config {
277 if let Ok(Some(config)) = config {
278 warnings.extend(config.warnings);
278 warnings.extend(config.warnings);
279 let mut m: Box<dyn Matcher + Sync> = Box::new(AlwaysMatcher);
279 let mut m: Box<dyn Matcher + Sync> = Box::new(AlwaysMatcher);
280 if !config.includes.is_empty() {
280 if !config.includes.is_empty() {
281 let (patterns, subwarnings) = parse_pattern_file_contents(
281 let (patterns, subwarnings) = parse_pattern_file_contents(
282 &config.includes,
282 &config.includes,
283 Path::new(""),
283 Path::new(""),
284 Some(b"relglob:".as_ref()),
284 Some(b"relglob:".as_ref()),
285 false,
285 false,
286 )?;
286 )?;
287 warnings.extend(subwarnings.into_iter().map(From::from));
287 warnings.extend(subwarnings.into_iter().map(From::from));
288 m = Box::new(IncludeMatcher::new(patterns)?);
288 m = Box::new(IncludeMatcher::new(patterns)?);
289 }
289 }
290 if !config.excludes.is_empty() {
290 if !config.excludes.is_empty() {
291 let (patterns, subwarnings) = parse_pattern_file_contents(
291 let (patterns, subwarnings) = parse_pattern_file_contents(
292 &config.excludes,
292 &config.excludes,
293 Path::new(""),
293 Path::new(""),
294 Some(b"relglob:".as_ref()),
294 Some(b"relglob:".as_ref()),
295 false,
295 false,
296 )?;
296 )?;
297 warnings.extend(subwarnings.into_iter().map(From::from));
297 warnings.extend(subwarnings.into_iter().map(From::from));
298 m = Box::new(DifferenceMatcher::new(
298 m = Box::new(DifferenceMatcher::new(
299 m,
299 m,
300 Box::new(IncludeMatcher::new(patterns)?),
300 Box::new(IncludeMatcher::new(patterns)?),
301 ));
301 ));
302 }
302 }
303 matchers.push(m);
303 matchers.push(m);
304 }
304 }
305 }
305 }
306 let result: Box<dyn Matcher + Sync> = match matchers.len() {
306 let result: Box<dyn Matcher + Sync> = match matchers.len() {
307 0 => Box::new(AlwaysMatcher),
307 0 => Box::new(AlwaysMatcher),
308 1 => matchers.pop().expect("1 is equal to 0"),
308 1 => matchers.pop().expect("1 is equal to 0"),
309 _ => Box::new(UnionMatcher::new(matchers)),
309 _ => Box::new(UnionMatcher::new(matchers)),
310 };
310 };
311
311
312 let matcher =
312 let matcher =
313 force_include_matcher(result, &read_temporary_includes(repo)?)?;
313 force_include_matcher(result, &read_temporary_includes(repo)?)?;
314 Ok((matcher, warnings))
314 Ok((matcher, warnings))
315 }
315 }
316
316
317 /// Returns a matcher that returns true for any of the forced includes before
317 /// Returns a matcher that returns true for any of the forced includes before
318 /// testing against the actual matcher
318 /// testing against the actual matcher
319 fn force_include_matcher(
319 fn force_include_matcher(
320 result: Box<dyn Matcher + Sync>,
320 result: Box<dyn Matcher + Sync>,
321 temp_includes: &[Vec<u8>],
321 temp_includes: &[Vec<u8>],
322 ) -> Result<Box<dyn Matcher + Sync>, PatternError> {
322 ) -> Result<Box<dyn Matcher + Sync>, PatternError> {
323 if temp_includes.is_empty() {
323 if temp_includes.is_empty() {
324 return Ok(result);
324 return Ok(result);
325 }
325 }
326 let forced_include_matcher = IncludeMatcher::new(
326 let forced_include_matcher = IncludeMatcher::new(
327 temp_includes
327 temp_includes
328 .into_iter()
328 .into_iter()
329 .map(|include| {
329 .map(|include| {
330 IgnorePattern::new(PatternSyntax::Path, include, Path::new(""))
330 IgnorePattern::new(PatternSyntax::Path, include, Path::new(""))
331 })
331 })
332 .collect(),
332 .collect(),
333 )?;
333 )?;
334 Ok(Box::new(UnionMatcher::new(vec![
334 Ok(Box::new(UnionMatcher::new(vec![
335 Box::new(forced_include_matcher),
335 Box::new(forced_include_matcher),
336 result,
336 result,
337 ])))
337 ])))
338 }
338 }
@@ -1,24 +1,25 b''
1 [package]
1 [package]
2 name = "rhg"
2 name = "rhg"
3 version = "0.1.0"
3 version = "0.1.0"
4 authors = [
4 authors = [
5 "Antoine Cezar <antoine.cezar@octobus.net>",
5 "Antoine Cezar <antoine.cezar@octobus.net>",
6 "Raphaël Gomès <raphael.gomes@octobus.net>",
6 "Raphaël Gomès <raphael.gomes@octobus.net>",
7 ]
7 ]
8 edition = "2018"
8 edition = "2018"
9
9
10 [dependencies]
10 [dependencies]
11 atty = "0.2.14"
11 atty = "0.2.14"
12 hg-core = { path = "../hg-core"}
12 hg-core = { path = "../hg-core"}
13 chrono = "0.4.19"
13 chrono = "0.4.19"
14 clap = "2.34.0"
14 clap = "2.34.0"
15 derive_more = "0.99.17"
15 derive_more = "0.99.17"
16 home = "0.5.3"
16 home = "0.5.3"
17 lazy_static = "1.4.0"
17 lazy_static = "1.4.0"
18 log = "0.4.14"
18 log = "0.4.14"
19 micro-timer = "0.4.0"
19 micro-timer = "0.4.0"
20 regex = "1.5.5"
20 regex = "1.5.5"
21 env_logger = "0.9.0"
21 env_logger = "0.9.0"
22 format-bytes = "0.3.0"
22 format-bytes = "0.3.0"
23 users = "0.11.0"
23 users = "0.11.0"
24 which = "4.2.5"
24 which = "4.2.5"
25 rayon = "1.5.1"
@@ -1,608 +1,625 b''
1 // status.rs
1 // status.rs
2 //
2 //
3 // Copyright 2020, Georges Racinet <georges.racinets@octobus.net>
3 // Copyright 2020, Georges Racinet <georges.racinets@octobus.net>
4 //
4 //
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 use crate::error::CommandError;
8 use crate::error::CommandError;
9 use crate::ui::Ui;
9 use crate::ui::Ui;
10 use crate::utils::path_utils::RelativizePaths;
10 use crate::utils::path_utils::RelativizePaths;
11 use clap::{Arg, SubCommand};
11 use clap::{Arg, SubCommand};
12 use format_bytes::format_bytes;
12 use format_bytes::format_bytes;
13 use hg::config::Config;
13 use hg::config::Config;
14 use hg::dirstate::has_exec_bit;
14 use hg::dirstate::has_exec_bit;
15 use hg::dirstate::status::StatusPath;
15 use hg::dirstate::status::StatusPath;
16 use hg::dirstate::TruncatedTimestamp;
16 use hg::dirstate::TruncatedTimestamp;
17 use hg::errors::{HgError, IoResultExt};
17 use hg::errors::{HgError, IoResultExt};
18 use hg::lock::LockError;
18 use hg::lock::LockError;
19 use hg::manifest::Manifest;
19 use hg::manifest::Manifest;
20 use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
20 use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
21 use hg::repo::Repo;
21 use hg::repo::Repo;
22 use hg::utils::files::get_bytes_from_os_string;
22 use hg::utils::files::get_bytes_from_os_string;
23 use hg::utils::files::get_bytes_from_path;
23 use hg::utils::files::get_bytes_from_path;
24 use hg::utils::files::get_path_from_bytes;
24 use hg::utils::files::get_path_from_bytes;
25 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
25 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
26 use hg::DirstateStatus;
26 use hg::DirstateStatus;
27 use hg::PatternFileWarning;
27 use hg::PatternFileWarning;
28 use hg::StatusError;
28 use hg::StatusError;
29 use hg::StatusOptions;
29 use hg::StatusOptions;
30 use hg::{self, narrow, sparse};
30 use hg::{self, narrow, sparse};
31 use log::info;
31 use log::info;
32 use rayon::prelude::*;
32 use std::io;
33 use std::io;
33 use std::path::PathBuf;
34 use std::path::PathBuf;
34
35
35 pub const HELP_TEXT: &str = "
36 pub const HELP_TEXT: &str = "
36 Show changed files in the working directory
37 Show changed files in the working directory
37
38
38 This is a pure Rust version of `hg status`.
39 This is a pure Rust version of `hg status`.
39
40
40 Some options might be missing, check the list below.
41 Some options might be missing, check the list below.
41 ";
42 ";
42
43
43 pub fn args() -> clap::App<'static, 'static> {
44 pub fn args() -> clap::App<'static, 'static> {
44 SubCommand::with_name("status")
45 SubCommand::with_name("status")
45 .alias("st")
46 .alias("st")
46 .about(HELP_TEXT)
47 .about(HELP_TEXT)
47 .arg(
48 .arg(
48 Arg::with_name("all")
49 Arg::with_name("all")
49 .help("show status of all files")
50 .help("show status of all files")
50 .short("-A")
51 .short("-A")
51 .long("--all"),
52 .long("--all"),
52 )
53 )
53 .arg(
54 .arg(
54 Arg::with_name("modified")
55 Arg::with_name("modified")
55 .help("show only modified files")
56 .help("show only modified files")
56 .short("-m")
57 .short("-m")
57 .long("--modified"),
58 .long("--modified"),
58 )
59 )
59 .arg(
60 .arg(
60 Arg::with_name("added")
61 Arg::with_name("added")
61 .help("show only added files")
62 .help("show only added files")
62 .short("-a")
63 .short("-a")
63 .long("--added"),
64 .long("--added"),
64 )
65 )
65 .arg(
66 .arg(
66 Arg::with_name("removed")
67 Arg::with_name("removed")
67 .help("show only removed files")
68 .help("show only removed files")
68 .short("-r")
69 .short("-r")
69 .long("--removed"),
70 .long("--removed"),
70 )
71 )
71 .arg(
72 .arg(
72 Arg::with_name("clean")
73 Arg::with_name("clean")
73 .help("show only clean files")
74 .help("show only clean files")
74 .short("-c")
75 .short("-c")
75 .long("--clean"),
76 .long("--clean"),
76 )
77 )
77 .arg(
78 .arg(
78 Arg::with_name("deleted")
79 Arg::with_name("deleted")
79 .help("show only deleted files")
80 .help("show only deleted files")
80 .short("-d")
81 .short("-d")
81 .long("--deleted"),
82 .long("--deleted"),
82 )
83 )
83 .arg(
84 .arg(
84 Arg::with_name("unknown")
85 Arg::with_name("unknown")
85 .help("show only unknown (not tracked) files")
86 .help("show only unknown (not tracked) files")
86 .short("-u")
87 .short("-u")
87 .long("--unknown"),
88 .long("--unknown"),
88 )
89 )
89 .arg(
90 .arg(
90 Arg::with_name("ignored")
91 Arg::with_name("ignored")
91 .help("show only ignored files")
92 .help("show only ignored files")
92 .short("-i")
93 .short("-i")
93 .long("--ignored"),
94 .long("--ignored"),
94 )
95 )
95 .arg(
96 .arg(
96 Arg::with_name("copies")
97 Arg::with_name("copies")
97 .help("show source of copied files (DEFAULT: ui.statuscopies)")
98 .help("show source of copied files (DEFAULT: ui.statuscopies)")
98 .short("-C")
99 .short("-C")
99 .long("--copies"),
100 .long("--copies"),
100 )
101 )
101 .arg(
102 .arg(
102 Arg::with_name("no-status")
103 Arg::with_name("no-status")
103 .help("hide status prefix")
104 .help("hide status prefix")
104 .short("-n")
105 .short("-n")
105 .long("--no-status"),
106 .long("--no-status"),
106 )
107 )
107 .arg(
108 .arg(
108 Arg::with_name("verbose")
109 Arg::with_name("verbose")
109 .help("enable additional output")
110 .help("enable additional output")
110 .short("-v")
111 .short("-v")
111 .long("--verbose"),
112 .long("--verbose"),
112 )
113 )
113 }
114 }
114
115
115 /// Pure data type allowing the caller to specify file states to display
116 /// Pure data type allowing the caller to specify file states to display
116 #[derive(Copy, Clone, Debug)]
117 #[derive(Copy, Clone, Debug)]
117 pub struct DisplayStates {
118 pub struct DisplayStates {
118 pub modified: bool,
119 pub modified: bool,
119 pub added: bool,
120 pub added: bool,
120 pub removed: bool,
121 pub removed: bool,
121 pub clean: bool,
122 pub clean: bool,
122 pub deleted: bool,
123 pub deleted: bool,
123 pub unknown: bool,
124 pub unknown: bool,
124 pub ignored: bool,
125 pub ignored: bool,
125 }
126 }
126
127
127 pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
128 pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
128 modified: true,
129 modified: true,
129 added: true,
130 added: true,
130 removed: true,
131 removed: true,
131 clean: false,
132 clean: false,
132 deleted: true,
133 deleted: true,
133 unknown: true,
134 unknown: true,
134 ignored: false,
135 ignored: false,
135 };
136 };
136
137
137 pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
138 pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
138 modified: true,
139 modified: true,
139 added: true,
140 added: true,
140 removed: true,
141 removed: true,
141 clean: true,
142 clean: true,
142 deleted: true,
143 deleted: true,
143 unknown: true,
144 unknown: true,
144 ignored: true,
145 ignored: true,
145 };
146 };
146
147
147 impl DisplayStates {
148 impl DisplayStates {
148 pub fn is_empty(&self) -> bool {
149 pub fn is_empty(&self) -> bool {
149 !(self.modified
150 !(self.modified
150 || self.added
151 || self.added
151 || self.removed
152 || self.removed
152 || self.clean
153 || self.clean
153 || self.deleted
154 || self.deleted
154 || self.unknown
155 || self.unknown
155 || self.ignored)
156 || self.ignored)
156 }
157 }
157 }
158 }
158
159
159 fn has_unfinished_merge(repo: &Repo) -> Result<bool, CommandError> {
160 fn has_unfinished_merge(repo: &Repo) -> Result<bool, CommandError> {
160 return Ok(repo.dirstate_parents()?.is_merge());
161 return Ok(repo.dirstate_parents()?.is_merge());
161 }
162 }
162
163
163 fn has_unfinished_state(repo: &Repo) -> Result<bool, CommandError> {
164 fn has_unfinished_state(repo: &Repo) -> Result<bool, CommandError> {
164 // These are all the known values for the [fname] argument of
165 // These are all the known values for the [fname] argument of
165 // [addunfinished] function in [state.py]
166 // [addunfinished] function in [state.py]
166 let known_state_files: &[&str] = &[
167 let known_state_files: &[&str] = &[
167 "bisect.state",
168 "bisect.state",
168 "graftstate",
169 "graftstate",
169 "histedit-state",
170 "histedit-state",
170 "rebasestate",
171 "rebasestate",
171 "shelvedstate",
172 "shelvedstate",
172 "transplant/journal",
173 "transplant/journal",
173 "updatestate",
174 "updatestate",
174 ];
175 ];
175 if has_unfinished_merge(repo)? {
176 if has_unfinished_merge(repo)? {
176 return Ok(true);
177 return Ok(true);
177 };
178 };
178 for f in known_state_files {
179 for f in known_state_files {
179 if repo.hg_vfs().join(f).exists() {
180 if repo.hg_vfs().join(f).exists() {
180 return Ok(true);
181 return Ok(true);
181 }
182 }
182 }
183 }
183 return Ok(false);
184 return Ok(false);
184 }
185 }
185
186
186 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
187 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
187 // TODO: lift these limitations
188 // TODO: lift these limitations
188 if invocation
189 if invocation
189 .config
190 .config
190 .get(b"commands", b"status.terse")
191 .get(b"commands", b"status.terse")
191 .is_some()
192 .is_some()
192 {
193 {
193 return Err(CommandError::unsupported(
194 return Err(CommandError::unsupported(
194 "status.terse is not yet supported with rhg status",
195 "status.terse is not yet supported with rhg status",
195 ));
196 ));
196 }
197 }
197
198
198 let ui = invocation.ui;
199 let ui = invocation.ui;
199 let config = invocation.config;
200 let config = invocation.config;
200 let args = invocation.subcommand_args;
201 let args = invocation.subcommand_args;
201
202
202 let verbose = !args.is_present("print0")
203 let verbose = !args.is_present("print0")
203 && (args.is_present("verbose")
204 && (args.is_present("verbose")
204 || config.get_bool(b"ui", b"verbose")?
205 || config.get_bool(b"ui", b"verbose")?
205 || config.get_bool(b"commands", b"status.verbose")?);
206 || config.get_bool(b"commands", b"status.verbose")?);
206
207
207 let all = args.is_present("all");
208 let all = args.is_present("all");
208 let display_states = if all {
209 let display_states = if all {
209 // TODO when implementing `--quiet`: it excludes clean files
210 // TODO when implementing `--quiet`: it excludes clean files
210 // from `--all`
211 // from `--all`
211 ALL_DISPLAY_STATES
212 ALL_DISPLAY_STATES
212 } else {
213 } else {
213 let requested = DisplayStates {
214 let requested = DisplayStates {
214 modified: args.is_present("modified"),
215 modified: args.is_present("modified"),
215 added: args.is_present("added"),
216 added: args.is_present("added"),
216 removed: args.is_present("removed"),
217 removed: args.is_present("removed"),
217 clean: args.is_present("clean"),
218 clean: args.is_present("clean"),
218 deleted: args.is_present("deleted"),
219 deleted: args.is_present("deleted"),
219 unknown: args.is_present("unknown"),
220 unknown: args.is_present("unknown"),
220 ignored: args.is_present("ignored"),
221 ignored: args.is_present("ignored"),
221 };
222 };
222 if requested.is_empty() {
223 if requested.is_empty() {
223 DEFAULT_DISPLAY_STATES
224 DEFAULT_DISPLAY_STATES
224 } else {
225 } else {
225 requested
226 requested
226 }
227 }
227 };
228 };
228 let no_status = args.is_present("no-status");
229 let no_status = args.is_present("no-status");
229 let list_copies = all
230 let list_copies = all
230 || args.is_present("copies")
231 || args.is_present("copies")
231 || config.get_bool(b"ui", b"statuscopies")?;
232 || config.get_bool(b"ui", b"statuscopies")?;
232
233
233 let repo = invocation.repo?;
234 let repo = invocation.repo?;
234
235
235 if verbose {
236 if verbose {
236 if has_unfinished_state(repo)? {
237 if has_unfinished_state(repo)? {
237 return Err(CommandError::unsupported(
238 return Err(CommandError::unsupported(
238 "verbose status output is not supported by rhg (and is needed because we're in an unfinished operation)",
239 "verbose status output is not supported by rhg (and is needed because we're in an unfinished operation)",
239 ));
240 ));
240 };
241 };
241 }
242 }
242
243
243 let mut dmap = repo.dirstate_map_mut()?;
244 let mut dmap = repo.dirstate_map_mut()?;
244
245
245 let options = StatusOptions {
246 let options = StatusOptions {
246 // we're currently supporting file systems with exec flags only
247 // we're currently supporting file systems with exec flags only
247 // anyway
248 // anyway
248 check_exec: true,
249 check_exec: true,
249 list_clean: display_states.clean,
250 list_clean: display_states.clean,
250 list_unknown: display_states.unknown,
251 list_unknown: display_states.unknown,
251 list_ignored: display_states.ignored,
252 list_ignored: display_states.ignored,
252 list_copies,
253 list_copies,
253 collect_traversed_dirs: false,
254 collect_traversed_dirs: false,
254 };
255 };
255
256
256 type StatusResult<'a> =
257 type StatusResult<'a> =
257 Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
258 Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
258
259
259 let after_status = |res: StatusResult| -> Result<_, CommandError> {
260 let after_status = |res: StatusResult| -> Result<_, CommandError> {
260 let (mut ds_status, pattern_warnings) = res?;
261 let (mut ds_status, pattern_warnings) = res?;
261 for warning in pattern_warnings {
262 for warning in pattern_warnings {
262 ui.write_stderr(&print_pattern_file_warning(&warning, &repo))?;
263 ui.write_stderr(&print_pattern_file_warning(&warning, &repo))?;
263 }
264 }
264
265
265 for (path, error) in ds_status.bad {
266 for (path, error) in ds_status.bad {
266 let error = match error {
267 let error = match error {
267 hg::BadMatch::OsError(code) => {
268 hg::BadMatch::OsError(code) => {
268 std::io::Error::from_raw_os_error(code).to_string()
269 std::io::Error::from_raw_os_error(code).to_string()
269 }
270 }
270 hg::BadMatch::BadType(ty) => {
271 hg::BadMatch::BadType(ty) => {
271 format!("unsupported file type (type is {})", ty)
272 format!("unsupported file type (type is {})", ty)
272 }
273 }
273 };
274 };
274 ui.write_stderr(&format_bytes!(
275 ui.write_stderr(&format_bytes!(
275 b"{}: {}\n",
276 b"{}: {}\n",
276 path.as_bytes(),
277 path.as_bytes(),
277 error.as_bytes()
278 error.as_bytes()
278 ))?
279 ))?
279 }
280 }
280 if !ds_status.unsure.is_empty() {
281 if !ds_status.unsure.is_empty() {
281 info!(
282 info!(
282 "Files to be rechecked by retrieval from filelog: {:?}",
283 "Files to be rechecked by retrieval from filelog: {:?}",
283 ds_status.unsure.iter().map(|s| &s.path).collect::<Vec<_>>()
284 ds_status.unsure.iter().map(|s| &s.path).collect::<Vec<_>>()
284 );
285 );
285 }
286 }
286 let mut fixup = Vec::new();
287 let mut fixup = Vec::new();
287 if !ds_status.unsure.is_empty()
288 if !ds_status.unsure.is_empty()
288 && (display_states.modified || display_states.clean)
289 && (display_states.modified || display_states.clean)
289 {
290 {
290 let p1 = repo.dirstate_parents()?.p1;
291 let p1 = repo.dirstate_parents()?.p1;
291 let manifest = repo.manifest_for_node(p1).map_err(|e| {
292 let manifest = repo.manifest_for_node(p1).map_err(|e| {
292 CommandError::from((e, &*format!("{:x}", p1.short())))
293 CommandError::from((e, &*format!("{:x}", p1.short())))
293 })?;
294 })?;
294 for to_check in ds_status.unsure {
295 let working_directory_vfs = repo.working_directory_vfs();
295 if unsure_is_modified(repo, &manifest, &to_check.path)? {
296 let store_vfs = repo.store_vfs();
297 let res: Vec<_> = ds_status
298 .unsure
299 .into_par_iter()
300 .map(|to_check| {
301 unsure_is_modified(
302 working_directory_vfs,
303 store_vfs,
304 &manifest,
305 &to_check.path,
306 )
307 .map(|modified| (to_check, modified))
308 })
309 .collect::<Result<_, _>>()?;
310 for (status_path, is_modified) in res.into_iter() {
311 if is_modified {
296 if display_states.modified {
312 if display_states.modified {
297 ds_status.modified.push(to_check);
313 ds_status.modified.push(status_path);
298 }
314 }
299 } else {
315 } else {
300 if display_states.clean {
316 if display_states.clean {
301 ds_status.clean.push(to_check.clone());
317 ds_status.clean.push(status_path.clone());
302 }
318 }
303 fixup.push(to_check.path.into_owned())
319 fixup.push(status_path.path.into_owned())
304 }
320 }
305 }
321 }
306 }
322 }
307 let relative_paths = config
323 let relative_paths = config
308 .get_option(b"commands", b"status.relative")?
324 .get_option(b"commands", b"status.relative")?
309 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
325 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
310 let output = DisplayStatusPaths {
326 let output = DisplayStatusPaths {
311 ui,
327 ui,
312 no_status,
328 no_status,
313 relativize: if relative_paths {
329 relativize: if relative_paths {
314 Some(RelativizePaths::new(repo)?)
330 Some(RelativizePaths::new(repo)?)
315 } else {
331 } else {
316 None
332 None
317 },
333 },
318 };
334 };
319 if display_states.modified {
335 if display_states.modified {
320 output.display(b"M ", "status.modified", ds_status.modified)?;
336 output.display(b"M ", "status.modified", ds_status.modified)?;
321 }
337 }
322 if display_states.added {
338 if display_states.added {
323 output.display(b"A ", "status.added", ds_status.added)?;
339 output.display(b"A ", "status.added", ds_status.added)?;
324 }
340 }
325 if display_states.removed {
341 if display_states.removed {
326 output.display(b"R ", "status.removed", ds_status.removed)?;
342 output.display(b"R ", "status.removed", ds_status.removed)?;
327 }
343 }
328 if display_states.deleted {
344 if display_states.deleted {
329 output.display(b"! ", "status.deleted", ds_status.deleted)?;
345 output.display(b"! ", "status.deleted", ds_status.deleted)?;
330 }
346 }
331 if display_states.unknown {
347 if display_states.unknown {
332 output.display(b"? ", "status.unknown", ds_status.unknown)?;
348 output.display(b"? ", "status.unknown", ds_status.unknown)?;
333 }
349 }
334 if display_states.ignored {
350 if display_states.ignored {
335 output.display(b"I ", "status.ignored", ds_status.ignored)?;
351 output.display(b"I ", "status.ignored", ds_status.ignored)?;
336 }
352 }
337 if display_states.clean {
353 if display_states.clean {
338 output.display(b"C ", "status.clean", ds_status.clean)?;
354 output.display(b"C ", "status.clean", ds_status.clean)?;
339 }
355 }
340
356
341 let dirstate_write_needed = ds_status.dirty;
357 let dirstate_write_needed = ds_status.dirty;
342 let filesystem_time_at_status_start =
358 let filesystem_time_at_status_start =
343 ds_status.filesystem_time_at_status_start;
359 ds_status.filesystem_time_at_status_start;
344
360
345 Ok((
361 Ok((
346 fixup,
362 fixup,
347 dirstate_write_needed,
363 dirstate_write_needed,
348 filesystem_time_at_status_start,
364 filesystem_time_at_status_start,
349 ))
365 ))
350 };
366 };
351 let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?;
367 let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?;
352 let (sparse_matcher, sparse_warnings) = sparse::matcher(repo)?;
368 let (sparse_matcher, sparse_warnings) = sparse::matcher(repo)?;
353 let matcher = match (repo.has_narrow(), repo.has_sparse()) {
369 let matcher = match (repo.has_narrow(), repo.has_sparse()) {
354 (true, true) => {
370 (true, true) => {
355 Box::new(IntersectionMatcher::new(narrow_matcher, sparse_matcher))
371 Box::new(IntersectionMatcher::new(narrow_matcher, sparse_matcher))
356 }
372 }
357 (true, false) => narrow_matcher,
373 (true, false) => narrow_matcher,
358 (false, true) => sparse_matcher,
374 (false, true) => sparse_matcher,
359 (false, false) => Box::new(AlwaysMatcher),
375 (false, false) => Box::new(AlwaysMatcher),
360 };
376 };
361
377
362 for warning in narrow_warnings.into_iter().chain(sparse_warnings) {
378 for warning in narrow_warnings.into_iter().chain(sparse_warnings) {
363 match &warning {
379 match &warning {
364 sparse::SparseWarning::RootWarning { context, line } => {
380 sparse::SparseWarning::RootWarning { context, line } => {
365 let msg = format_bytes!(
381 let msg = format_bytes!(
366 b"warning: {} profile cannot use paths \"
382 b"warning: {} profile cannot use paths \"
367 starting with /, ignoring {}\n",
383 starting with /, ignoring {}\n",
368 context,
384 context,
369 line
385 line
370 );
386 );
371 ui.write_stderr(&msg)?;
387 ui.write_stderr(&msg)?;
372 }
388 }
373 sparse::SparseWarning::ProfileNotFound { profile, rev } => {
389 sparse::SparseWarning::ProfileNotFound { profile, rev } => {
374 let msg = format_bytes!(
390 let msg = format_bytes!(
375 b"warning: sparse profile '{}' not found \"
391 b"warning: sparse profile '{}' not found \"
376 in rev {} - ignoring it\n",
392 in rev {} - ignoring it\n",
377 profile,
393 profile,
378 rev
394 rev
379 );
395 );
380 ui.write_stderr(&msg)?;
396 ui.write_stderr(&msg)?;
381 }
397 }
382 sparse::SparseWarning::Pattern(e) => {
398 sparse::SparseWarning::Pattern(e) => {
383 ui.write_stderr(&print_pattern_file_warning(e, &repo))?;
399 ui.write_stderr(&print_pattern_file_warning(e, &repo))?;
384 }
400 }
385 }
401 }
386 }
402 }
387 let (fixup, mut dirstate_write_needed, filesystem_time_at_status_start) =
403 let (fixup, mut dirstate_write_needed, filesystem_time_at_status_start) =
388 dmap.with_status(
404 dmap.with_status(
389 matcher.as_ref(),
405 matcher.as_ref(),
390 repo.working_directory_path().to_owned(),
406 repo.working_directory_path().to_owned(),
391 ignore_files(repo, config),
407 ignore_files(repo, config),
392 options,
408 options,
393 after_status,
409 after_status,
394 )?;
410 )?;
395
411
396 if (fixup.is_empty() || filesystem_time_at_status_start.is_none())
412 if (fixup.is_empty() || filesystem_time_at_status_start.is_none())
397 && !dirstate_write_needed
413 && !dirstate_write_needed
398 {
414 {
399 // Nothing to update
415 // Nothing to update
400 return Ok(());
416 return Ok(());
401 }
417 }
402
418
403 // Update the dirstate on disk if we can
419 // Update the dirstate on disk if we can
404 let with_lock_result =
420 let with_lock_result =
405 repo.try_with_wlock_no_wait(|| -> Result<(), CommandError> {
421 repo.try_with_wlock_no_wait(|| -> Result<(), CommandError> {
406 if let Some(mtime_boundary) = filesystem_time_at_status_start {
422 if let Some(mtime_boundary) = filesystem_time_at_status_start {
407 for hg_path in fixup {
423 for hg_path in fixup {
408 use std::os::unix::fs::MetadataExt;
424 use std::os::unix::fs::MetadataExt;
409 let fs_path = hg_path_to_path_buf(&hg_path)
425 let fs_path = hg_path_to_path_buf(&hg_path)
410 .expect("HgPath conversion");
426 .expect("HgPath conversion");
411 // Specifically do not reuse `fs_metadata` from
427 // Specifically do not reuse `fs_metadata` from
412 // `unsure_is_clean` which was needed before reading
428 // `unsure_is_clean` which was needed before reading
413 // contents. Here we access metadata again after reading
429 // contents. Here we access metadata again after reading
414 // content, in case it changed in the meantime.
430 // content, in case it changed in the meantime.
415 let fs_metadata = repo
431 let fs_metadata = repo
416 .working_directory_vfs()
432 .working_directory_vfs()
417 .symlink_metadata(&fs_path)?;
433 .symlink_metadata(&fs_path)?;
418 if let Some(mtime) =
434 if let Some(mtime) =
419 TruncatedTimestamp::for_reliable_mtime_of(
435 TruncatedTimestamp::for_reliable_mtime_of(
420 &fs_metadata,
436 &fs_metadata,
421 &mtime_boundary,
437 &mtime_boundary,
422 )
438 )
423 .when_reading_file(&fs_path)?
439 .when_reading_file(&fs_path)?
424 {
440 {
425 let mode = fs_metadata.mode();
441 let mode = fs_metadata.mode();
426 let size = fs_metadata.len();
442 let size = fs_metadata.len();
427 dmap.set_clean(&hg_path, mode, size as u32, mtime)?;
443 dmap.set_clean(&hg_path, mode, size as u32, mtime)?;
428 dirstate_write_needed = true
444 dirstate_write_needed = true
429 }
445 }
430 }
446 }
431 }
447 }
432 drop(dmap); // Avoid "already mutably borrowed" RefCell panics
448 drop(dmap); // Avoid "already mutably borrowed" RefCell panics
433 if dirstate_write_needed {
449 if dirstate_write_needed {
434 repo.write_dirstate()?
450 repo.write_dirstate()?
435 }
451 }
436 Ok(())
452 Ok(())
437 });
453 });
438 match with_lock_result {
454 match with_lock_result {
439 Ok(closure_result) => closure_result?,
455 Ok(closure_result) => closure_result?,
440 Err(LockError::AlreadyHeld) => {
456 Err(LockError::AlreadyHeld) => {
441 // Not updating the dirstate is not ideal but not critical:
457 // Not updating the dirstate is not ideal but not critical:
442 // don’t keep our caller waiting until some other Mercurial
458 // don’t keep our caller waiting until some other Mercurial
443 // process releases the lock.
459 // process releases the lock.
444 }
460 }
445 Err(LockError::Other(HgError::IoError { error, .. }))
461 Err(LockError::Other(HgError::IoError { error, .. }))
446 if error.kind() == io::ErrorKind::PermissionDenied =>
462 if error.kind() == io::ErrorKind::PermissionDenied =>
447 {
463 {
448 // `hg status` on a read-only repository is fine
464 // `hg status` on a read-only repository is fine
449 }
465 }
450 Err(LockError::Other(error)) => {
466 Err(LockError::Other(error)) => {
451 // Report other I/O errors
467 // Report other I/O errors
452 Err(error)?
468 Err(error)?
453 }
469 }
454 }
470 }
455 Ok(())
471 Ok(())
456 }
472 }
457
473
458 fn ignore_files(repo: &Repo, config: &Config) -> Vec<PathBuf> {
474 fn ignore_files(repo: &Repo, config: &Config) -> Vec<PathBuf> {
459 let mut ignore_files = Vec::new();
475 let mut ignore_files = Vec::new();
460 let repo_ignore = repo.working_directory_vfs().join(".hgignore");
476 let repo_ignore = repo.working_directory_vfs().join(".hgignore");
461 if repo_ignore.exists() {
477 if repo_ignore.exists() {
462 ignore_files.push(repo_ignore)
478 ignore_files.push(repo_ignore)
463 }
479 }
464 for (key, value) in config.iter_section(b"ui") {
480 for (key, value) in config.iter_section(b"ui") {
465 if key == b"ignore" || key.starts_with(b"ignore.") {
481 if key == b"ignore" || key.starts_with(b"ignore.") {
466 let path = get_path_from_bytes(value);
482 let path = get_path_from_bytes(value);
467 // TODO:Β expand "~/" and environment variable here, like Python
483 // TODO:Β expand "~/" and environment variable here, like Python
468 // does with `os.path.expanduser` and `os.path.expandvars`
484 // does with `os.path.expanduser` and `os.path.expandvars`
469
485
470 let joined = repo.working_directory_path().join(path);
486 let joined = repo.working_directory_path().join(path);
471 ignore_files.push(joined);
487 ignore_files.push(joined);
472 }
488 }
473 }
489 }
474 ignore_files
490 ignore_files
475 }
491 }
476
492
477 struct DisplayStatusPaths<'a> {
493 struct DisplayStatusPaths<'a> {
478 ui: &'a Ui,
494 ui: &'a Ui,
479 no_status: bool,
495 no_status: bool,
480 relativize: Option<RelativizePaths>,
496 relativize: Option<RelativizePaths>,
481 }
497 }
482
498
483 impl DisplayStatusPaths<'_> {
499 impl DisplayStatusPaths<'_> {
484 // Probably more elegant to use a Deref or Borrow trait rather than
500 // Probably more elegant to use a Deref or Borrow trait rather than
485 // harcode HgPathBuf, but probably not really useful at this point
501 // harcode HgPathBuf, but probably not really useful at this point
486 fn display(
502 fn display(
487 &self,
503 &self,
488 status_prefix: &[u8],
504 status_prefix: &[u8],
489 label: &'static str,
505 label: &'static str,
490 mut paths: Vec<StatusPath<'_>>,
506 mut paths: Vec<StatusPath<'_>>,
491 ) -> Result<(), CommandError> {
507 ) -> Result<(), CommandError> {
492 paths.sort_unstable();
508 paths.sort_unstable();
493 // TODO: get the stdout lock once for the whole loop
509 // TODO: get the stdout lock once for the whole loop
494 // instead of in each write
510 // instead of in each write
495 for StatusPath { path, copy_source } in paths {
511 for StatusPath { path, copy_source } in paths {
496 let relative;
512 let relative;
497 let path = if let Some(relativize) = &self.relativize {
513 let path = if let Some(relativize) = &self.relativize {
498 relative = relativize.relativize(&path);
514 relative = relativize.relativize(&path);
499 &*relative
515 &*relative
500 } else {
516 } else {
501 path.as_bytes()
517 path.as_bytes()
502 };
518 };
503 // TODO: Add a way to use `write_bytes!` instead of `format_bytes!`
519 // TODO: Add a way to use `write_bytes!` instead of `format_bytes!`
504 // in order to stream to stdout instead of allocating an
520 // in order to stream to stdout instead of allocating an
505 // itermediate `Vec<u8>`.
521 // itermediate `Vec<u8>`.
506 if !self.no_status {
522 if !self.no_status {
507 self.ui.write_stdout_labelled(status_prefix, label)?
523 self.ui.write_stdout_labelled(status_prefix, label)?
508 }
524 }
509 self.ui
525 self.ui
510 .write_stdout_labelled(&format_bytes!(b"{}\n", path), label)?;
526 .write_stdout_labelled(&format_bytes!(b"{}\n", path), label)?;
511 if let Some(source) = copy_source {
527 if let Some(source) = copy_source {
512 let label = "status.copied";
528 let label = "status.copied";
513 self.ui.write_stdout_labelled(
529 self.ui.write_stdout_labelled(
514 &format_bytes!(b" {}\n", source.as_bytes()),
530 &format_bytes!(b" {}\n", source.as_bytes()),
515 label,
531 label,
516 )?
532 )?
517 }
533 }
518 }
534 }
519 Ok(())
535 Ok(())
520 }
536 }
521 }
537 }
522
538
523 /// Check if a file is modified by comparing actual repo store and file system.
539 /// Check if a file is modified by comparing actual repo store and file system.
524 ///
540 ///
525 /// This meant to be used for those that the dirstate cannot resolve, due
541 /// This meant to be used for those that the dirstate cannot resolve, due
526 /// to time resolution limits.
542 /// to time resolution limits.
527 fn unsure_is_modified(
543 fn unsure_is_modified(
528 repo: &Repo,
544 working_directory_vfs: hg::vfs::Vfs,
545 store_vfs: hg::vfs::Vfs,
529 manifest: &Manifest,
546 manifest: &Manifest,
530 hg_path: &HgPath,
547 hg_path: &HgPath,
531 ) -> Result<bool, HgError> {
548 ) -> Result<bool, HgError> {
532 let vfs = repo.working_directory_vfs();
549 let vfs = working_directory_vfs;
533 let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion");
550 let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion");
534 let fs_metadata = vfs.symlink_metadata(&fs_path)?;
551 let fs_metadata = vfs.symlink_metadata(&fs_path)?;
535 let is_symlink = fs_metadata.file_type().is_symlink();
552 let is_symlink = fs_metadata.file_type().is_symlink();
536 // TODO: Also account for `FALLBACK_SYMLINK` and `FALLBACK_EXEC` from the
553 // TODO: Also account for `FALLBACK_SYMLINK` and `FALLBACK_EXEC` from the
537 // dirstate
554 // dirstate
538 let fs_flags = if is_symlink {
555 let fs_flags = if is_symlink {
539 Some(b'l')
556 Some(b'l')
540 } else if has_exec_bit(&fs_metadata) {
557 } else if has_exec_bit(&fs_metadata) {
541 Some(b'x')
558 Some(b'x')
542 } else {
559 } else {
543 None
560 None
544 };
561 };
545
562
546 let entry = manifest
563 let entry = manifest
547 .find_by_path(hg_path)?
564 .find_by_path(hg_path)?
548 .expect("ambgious file not in p1");
565 .expect("ambgious file not in p1");
549 if entry.flags != fs_flags {
566 if entry.flags != fs_flags {
550 return Ok(true);
567 return Ok(true);
551 }
568 }
552 let filelog = repo.filelog(hg_path)?;
569 let filelog = hg::filelog::Filelog::open_vfs(&store_vfs, hg_path)?;
553 let fs_len = fs_metadata.len();
570 let fs_len = fs_metadata.len();
554 let file_node = entry.node_id()?;
571 let file_node = entry.node_id()?;
555 let filelog_entry = filelog.entry_for_node(file_node).map_err(|_| {
572 let filelog_entry = filelog.entry_for_node(file_node).map_err(|_| {
556 HgError::corrupted(format!(
573 HgError::corrupted(format!(
557 "filelog missing node {:?} from manifest",
574 "filelog missing node {:?} from manifest",
558 file_node
575 file_node
559 ))
576 ))
560 })?;
577 })?;
561 if filelog_entry.file_data_len_not_equal_to(fs_len) {
578 if filelog_entry.file_data_len_not_equal_to(fs_len) {
562 // No need to read file contents:
579 // No need to read file contents:
563 // it cannot be equal if it has a different length.
580 // it cannot be equal if it has a different length.
564 return Ok(true);
581 return Ok(true);
565 }
582 }
566
583
567 let p1_filelog_data = filelog_entry.data()?;
584 let p1_filelog_data = filelog_entry.data()?;
568 let p1_contents = p1_filelog_data.file_data()?;
585 let p1_contents = p1_filelog_data.file_data()?;
569 if p1_contents.len() as u64 != fs_len {
586 if p1_contents.len() as u64 != fs_len {
570 // No need to read file contents:
587 // No need to read file contents:
571 // it cannot be equal if it has a different length.
588 // it cannot be equal if it has a different length.
572 return Ok(true);
589 return Ok(true);
573 }
590 }
574
591
575 let fs_contents = if is_symlink {
592 let fs_contents = if is_symlink {
576 get_bytes_from_os_string(vfs.read_link(fs_path)?.into_os_string())
593 get_bytes_from_os_string(vfs.read_link(fs_path)?.into_os_string())
577 } else {
594 } else {
578 vfs.read(fs_path)?
595 vfs.read(fs_path)?
579 };
596 };
580 Ok(p1_contents != &*fs_contents)
597 Ok(p1_contents != &*fs_contents)
581 }
598 }
582
599
583 fn print_pattern_file_warning(
600 fn print_pattern_file_warning(
584 warning: &PatternFileWarning,
601 warning: &PatternFileWarning,
585 repo: &Repo,
602 repo: &Repo,
586 ) -> Vec<u8> {
603 ) -> Vec<u8> {
587 match warning {
604 match warning {
588 PatternFileWarning::InvalidSyntax(path, syntax) => format_bytes!(
605 PatternFileWarning::InvalidSyntax(path, syntax) => format_bytes!(
589 b"{}: ignoring invalid syntax '{}'\n",
606 b"{}: ignoring invalid syntax '{}'\n",
590 get_bytes_from_path(path),
607 get_bytes_from_path(path),
591 &*syntax
608 &*syntax
592 ),
609 ),
593 PatternFileWarning::NoSuchFile(path) => {
610 PatternFileWarning::NoSuchFile(path) => {
594 let path = if let Ok(relative) =
611 let path = if let Ok(relative) =
595 path.strip_prefix(repo.working_directory_path())
612 path.strip_prefix(repo.working_directory_path())
596 {
613 {
597 relative
614 relative
598 } else {
615 } else {
599 &*path
616 &*path
600 };
617 };
601 format_bytes!(
618 format_bytes!(
602 b"skipping unreadable pattern file '{}': \
619 b"skipping unreadable pattern file '{}': \
603 No such file or directory\n",
620 No such file or directory\n",
604 get_bytes_from_path(path),
621 get_bytes_from_path(path),
605 )
622 )
606 }
623 }
607 }
624 }
608 }
625 }
General Comments 0
You need to be logged in to leave comments. Login now