##// END OF EJS Templates
rust: pure Rust lazyancestors iterator...
Georges Racinet -
r40307:dbc28c91 default
parent child Browse files
Show More
@@ -0,0 +1,8 b''
1 [package]
2 name = "hg-core"
3 version = "0.1.0"
4 authors = ["Georges Racinet <gracinet@anybox.fr>"]
5 description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)"
6
7 [lib]
8 name = "hg"
@@ -0,0 +1,3 b''
1 max_width = 79
2 wrap_comments = true
3 error_on_line_overflow = true
@@ -0,0 +1,238 b''
1 // ancestors.rs
2 //
3 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
4 //
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.
7
8 //! Rust versions of generic DAG ancestors algorithms for Mercurial
9
10 use super::{Graph, GraphError, Revision, NULL_REVISION};
11 use std::collections::{BinaryHeap, HashSet};
12
13 /// Iterator over the ancestors of a given list of revisions
14 /// This is a generic type, defined and implemented for any Graph, so that
15 /// it's easy to
16 ///
17 /// - unit test in pure Rust
18 /// - bind to main Mercurial code, potentially in several ways and have these
19 /// bindings evolve over time
20 pub struct AncestorsIterator<G: Graph> {
21 graph: G,
22 visit: BinaryHeap<Revision>,
23 seen: HashSet<Revision>,
24 stoprev: Revision,
25 }
26
27 impl<G: Graph> AncestorsIterator<G> {
28 /// Constructor.
29 ///
30 /// if `inclusive` is true, then the init revisions are emitted in
31 /// particular, otherwise iteration starts from their parents.
32 pub fn new<I>(
33 graph: G,
34 initrevs: I,
35 stoprev: Revision,
36 inclusive: bool,
37 ) -> Result<Self, GraphError>
38 where
39 I: IntoIterator<Item = Revision>,
40 {
41 let filtered_initrevs = initrevs.into_iter().filter(|&r| r >= stoprev);
42 if inclusive {
43 let visit: BinaryHeap<Revision> = filtered_initrevs.collect();
44 let seen = visit.iter().map(|&x| x).collect();
45 return Ok(AncestorsIterator {
46 visit: visit,
47 seen: seen,
48 stoprev: stoprev,
49 graph: graph,
50 });
51 }
52 let mut this = AncestorsIterator {
53 visit: BinaryHeap::new(),
54 seen: HashSet::new(),
55 stoprev: stoprev,
56 graph: graph,
57 };
58 this.seen.insert(NULL_REVISION);
59 for rev in filtered_initrevs {
60 this.conditionally_push_parents(rev)?;
61 }
62 Ok(this)
63 }
64
65 #[inline]
66 fn conditionally_push_rev(&mut self, rev: Revision) {
67 if self.stoprev <= rev && !self.seen.contains(&rev) {
68 self.seen.insert(rev);
69 self.visit.push(rev);
70 }
71 }
72
73 #[inline]
74 fn conditionally_push_parents(
75 &mut self,
76 rev: Revision,
77 ) -> Result<(), GraphError> {
78 let parents = self.graph.parents(rev)?;
79 self.conditionally_push_rev(parents.0);
80 self.conditionally_push_rev(parents.1);
81 Ok(())
82 }
83 }
84
85 /// Main implementation.
86 ///
87 /// The algorithm is the same as in `_lazyancestorsiter()` from `ancestors.py`
88 /// with a few non crucial differences:
89 ///
90 /// - there's no filtering of invalid parent revisions. Actually, it should be
91 /// consistent and more efficient to filter them from the end caller.
92 /// - we don't use the equivalent of `heapq.heapreplace()`, but we should, for
93 /// the same reasons (using `peek_mut`)
94 /// - we don't have the optimization for adjacent revs (case where p1 == rev-1)
95 /// - we save a few pushes by comparing with `stoprev` before pushing
96 ///
97 /// Error treatment:
98 /// We swallow the possible GraphError of conditionally_push_parents() to
99 /// respect the Iterator trait in a simple manner: never emitting parents
100 /// for the returned revision. We finds this good enough for now, because:
101 ///
102 /// - there's a good chance that invalid revisionss are fed from the start,
103 /// and `new()` doesn't swallow the error result.
104 /// - this is probably what the Python implementation produces anyway, due
105 /// to filtering at each step, and Python code is currently the only
106 /// concrete caller we target, so we shouldn't need a finer error treatment
107 /// for the time being.
108 impl<G: Graph> Iterator for AncestorsIterator<G> {
109 type Item = Revision;
110
111 fn next(&mut self) -> Option<Revision> {
112 let current = match self.visit.pop() {
113 None => {
114 return None;
115 }
116 Some(i) => i,
117 };
118 self.conditionally_push_parents(current).unwrap_or(());
119 Some(current)
120 }
121 }
122
123 #[cfg(test)]
124 mod tests {
125
126 use super::*;
127
128 #[derive(Clone, Debug)]
129 struct Stub;
130
131 /// This is the same as the dict from test-ancestors.py
132 impl Graph for Stub {
133 fn parents(
134 &self,
135 rev: Revision,
136 ) -> Result<(Revision, Revision), GraphError> {
137 match rev {
138 0 => Ok((-1, -1)),
139 1 => Ok((0, -1)),
140 2 => Ok((1, -1)),
141 3 => Ok((1, -1)),
142 4 => Ok((2, -1)),
143 5 => Ok((4, -1)),
144 6 => Ok((4, -1)),
145 7 => Ok((4, -1)),
146 8 => Ok((-1, -1)),
147 9 => Ok((6, 7)),
148 10 => Ok((5, -1)),
149 11 => Ok((3, 7)),
150 12 => Ok((9, -1)),
151 13 => Ok((8, -1)),
152 r => Err(GraphError::ParentOutOfRange(r)),
153 }
154 }
155 }
156
157 fn list_ancestors<G: Graph>(
158 graph: G,
159 initrevs: Vec<Revision>,
160 stoprev: Revision,
161 inclusive: bool,
162 ) -> Vec<Revision> {
163 AncestorsIterator::new(graph, initrevs, stoprev, inclusive)
164 .unwrap()
165 .collect()
166 }
167
168 #[test]
169 /// Same tests as test-ancestor.py, without membership
170 /// (see also test-ancestor.py.out)
171 fn test_list_ancestor() {
172 assert_eq!(list_ancestors(Stub, vec![], 0, false), vec![]);
173 assert_eq!(
174 list_ancestors(Stub, vec![11, 13], 0, false),
175 vec![8, 7, 4, 3, 2, 1, 0]
176 );
177 assert_eq!(list_ancestors(Stub, vec![1, 3], 0, false), vec![1, 0]);
178 assert_eq!(
179 list_ancestors(Stub, vec![11, 13], 0, true),
180 vec![13, 11, 8, 7, 4, 3, 2, 1, 0]
181 );
182 assert_eq!(list_ancestors(Stub, vec![11, 13], 6, false), vec![8, 7]);
183 assert_eq!(
184 list_ancestors(Stub, vec![11, 13], 6, true),
185 vec![13, 11, 8, 7]
186 );
187 assert_eq!(list_ancestors(Stub, vec![11, 13], 11, true), vec![13, 11]);
188 assert_eq!(list_ancestors(Stub, vec![11, 13], 12, true), vec![13]);
189 assert_eq!(
190 list_ancestors(Stub, vec![10, 1], 0, true),
191 vec![10, 5, 4, 2, 1, 0]
192 );
193 }
194
195 #[test]
196 /// Corner case that's not directly in test-ancestors.py, but
197 /// that happens quite often, as demonstrated by running the whole
198 /// suite.
199 /// For instance, run tests/test-obsolete-checkheads.t
200 fn test_nullrev_input() {
201 let mut iter =
202 AncestorsIterator::new(Stub, vec![-1], 0, false).unwrap();
203 assert_eq!(iter.next(), None)
204 }
205
206 /// A corrupted Graph, supporting error handling tests
207 struct Corrupted;
208
209 impl Graph for Corrupted {
210 fn parents(
211 &self,
212 rev: Revision,
213 ) -> Result<(Revision, Revision), GraphError> {
214 match rev {
215 1 => Ok((0, -1)),
216 r => Err(GraphError::ParentOutOfRange(r)),
217 }
218 }
219 }
220
221 #[test]
222 fn test_initrev_out_of_range() {
223 // inclusive=false looks up initrev's parents right away
224 match AncestorsIterator::new(Stub, vec![25], 0, false) {
225 Ok(_) => panic!("Should have been ParentOutOfRange"),
226 Err(e) => assert_eq!(e, GraphError::ParentOutOfRange(25)),
227 }
228 }
229
230 #[test]
231 fn test_next_out_of_range() {
232 // inclusive=false looks up initrev's parents right away
233 let mut iter =
234 AncestorsIterator::new(Corrupted, vec![1], 0, false).unwrap();
235 assert_eq!(iter.next(), Some(0));
236 assert_eq!(iter.next(), None);
237 }
238 }
@@ -0,0 +1,24 b''
1 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
2 //
3 // This software may be used and distributed according to the terms of the
4 // GNU General Public License version 2 or any later version.
5 mod ancestors;
6 pub use ancestors::AncestorsIterator;
7
8 /// Mercurial revision numbers
9 ///
10 /// As noted in revlog.c, revision numbers are actually encoded in
11 /// 4 bytes, and are liberally converted to ints, whence the i32
12 pub type Revision = i32;
13
14 pub const NULL_REVISION: Revision = -1;
15
16 /// The simplest expression of what we need of Mercurial DAGs.
17 pub trait Graph {
18 fn parents(&self, Revision) -> Result<(Revision, Revision), GraphError>;
19 }
20
21 #[derive(Clone, Debug, PartialEq)]
22 pub enum GraphError {
23 ParentOutOfRange(Revision),
24 }
@@ -1,127 +1,131 b''
1 [[package]]
1 [[package]]
2 name = "aho-corasick"
2 name = "aho-corasick"
3 version = "0.5.3"
3 version = "0.5.3"
4 source = "registry+https://github.com/rust-lang/crates.io-index"
4 source = "registry+https://github.com/rust-lang/crates.io-index"
5 dependencies = [
5 dependencies = [
6 "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
6 "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
7 ]
7 ]
8
8
9 [[package]]
9 [[package]]
10 name = "cpython"
10 name = "cpython"
11 version = "0.1.0"
11 version = "0.1.0"
12 source = "git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52#c90d65cf84abfffce7ef54476bbfed56017a2f52"
12 source = "git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52#c90d65cf84abfffce7ef54476bbfed56017a2f52"
13 dependencies = [
13 dependencies = [
14 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
14 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
15 "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
15 "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
16 "python27-sys 0.1.2 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)",
16 "python27-sys 0.1.2 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)",
17 ]
17 ]
18
18
19 [[package]]
19 [[package]]
20 name = "hg-core"
21 version = "0.1.0"
22
23 [[package]]
20 name = "hgcli"
24 name = "hgcli"
21 version = "0.1.0"
25 version = "0.1.0"
22 dependencies = [
26 dependencies = [
23 "cpython 0.1.0 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)",
27 "cpython 0.1.0 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)",
24 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
28 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
25 "python27-sys 0.1.2 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)",
29 "python27-sys 0.1.2 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)",
26 ]
30 ]
27
31
28 [[package]]
32 [[package]]
29 name = "kernel32-sys"
33 name = "kernel32-sys"
30 version = "0.2.2"
34 version = "0.2.2"
31 source = "registry+https://github.com/rust-lang/crates.io-index"
35 source = "registry+https://github.com/rust-lang/crates.io-index"
32 dependencies = [
36 dependencies = [
33 "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
37 "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
34 "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
38 "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
35 ]
39 ]
36
40
37 [[package]]
41 [[package]]
38 name = "libc"
42 name = "libc"
39 version = "0.2.35"
43 version = "0.2.35"
40 source = "registry+https://github.com/rust-lang/crates.io-index"
44 source = "registry+https://github.com/rust-lang/crates.io-index"
41
45
42 [[package]]
46 [[package]]
43 name = "memchr"
47 name = "memchr"
44 version = "0.1.11"
48 version = "0.1.11"
45 source = "registry+https://github.com/rust-lang/crates.io-index"
49 source = "registry+https://github.com/rust-lang/crates.io-index"
46 dependencies = [
50 dependencies = [
47 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
51 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
48 ]
52 ]
49
53
50 [[package]]
54 [[package]]
51 name = "num-traits"
55 name = "num-traits"
52 version = "0.1.41"
56 version = "0.1.41"
53 source = "registry+https://github.com/rust-lang/crates.io-index"
57 source = "registry+https://github.com/rust-lang/crates.io-index"
54
58
55 [[package]]
59 [[package]]
56 name = "python27-sys"
60 name = "python27-sys"
57 version = "0.1.2"
61 version = "0.1.2"
58 source = "git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52#c90d65cf84abfffce7ef54476bbfed56017a2f52"
62 source = "git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52#c90d65cf84abfffce7ef54476bbfed56017a2f52"
59 dependencies = [
63 dependencies = [
60 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
64 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
61 "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
65 "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
62 ]
66 ]
63
67
64 [[package]]
68 [[package]]
65 name = "regex"
69 name = "regex"
66 version = "0.1.80"
70 version = "0.1.80"
67 source = "registry+https://github.com/rust-lang/crates.io-index"
71 source = "registry+https://github.com/rust-lang/crates.io-index"
68 dependencies = [
72 dependencies = [
69 "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
73 "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
70 "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
74 "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
71 "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
75 "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
72 "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
76 "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
73 "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
77 "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
74 ]
78 ]
75
79
76 [[package]]
80 [[package]]
77 name = "regex-syntax"
81 name = "regex-syntax"
78 version = "0.3.9"
82 version = "0.3.9"
79 source = "registry+https://github.com/rust-lang/crates.io-index"
83 source = "registry+https://github.com/rust-lang/crates.io-index"
80
84
81 [[package]]
85 [[package]]
82 name = "thread-id"
86 name = "thread-id"
83 version = "2.0.0"
87 version = "2.0.0"
84 source = "registry+https://github.com/rust-lang/crates.io-index"
88 source = "registry+https://github.com/rust-lang/crates.io-index"
85 dependencies = [
89 dependencies = [
86 "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
90 "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
87 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
91 "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
88 ]
92 ]
89
93
90 [[package]]
94 [[package]]
91 name = "thread_local"
95 name = "thread_local"
92 version = "0.2.7"
96 version = "0.2.7"
93 source = "registry+https://github.com/rust-lang/crates.io-index"
97 source = "registry+https://github.com/rust-lang/crates.io-index"
94 dependencies = [
98 dependencies = [
95 "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
99 "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
96 ]
100 ]
97
101
98 [[package]]
102 [[package]]
99 name = "utf8-ranges"
103 name = "utf8-ranges"
100 version = "0.1.3"
104 version = "0.1.3"
101 source = "registry+https://github.com/rust-lang/crates.io-index"
105 source = "registry+https://github.com/rust-lang/crates.io-index"
102
106
103 [[package]]
107 [[package]]
104 name = "winapi"
108 name = "winapi"
105 version = "0.2.8"
109 version = "0.2.8"
106 source = "registry+https://github.com/rust-lang/crates.io-index"
110 source = "registry+https://github.com/rust-lang/crates.io-index"
107
111
108 [[package]]
112 [[package]]
109 name = "winapi-build"
113 name = "winapi-build"
110 version = "0.1.1"
114 version = "0.1.1"
111 source = "registry+https://github.com/rust-lang/crates.io-index"
115 source = "registry+https://github.com/rust-lang/crates.io-index"
112
116
113 [metadata]
117 [metadata]
114 "checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
118 "checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
115 "checksum cpython 0.1.0 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)" = "<none>"
119 "checksum cpython 0.1.0 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)" = "<none>"
116 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
120 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
117 "checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb"
121 "checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb"
118 "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
122 "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
119 "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
123 "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
120 "checksum python27-sys 0.1.2 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)" = "<none>"
124 "checksum python27-sys 0.1.2 (git+https://github.com/indygreg/rust-cpython.git?rev=c90d65cf84abfffce7ef54476bbfed56017a2f52)" = "<none>"
121 "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
125 "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
122 "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
126 "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
123 "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
127 "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
124 "checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
128 "checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
125 "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
129 "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
126 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
130 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
127 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
131 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
@@ -1,3 +1,3 b''
1 [workspace]
1 [workspace]
2 members = ["hgcli"]
2 members = ["hgcli", "hg-core"]
3 exclude = ["chg"]
3 exclude = ["chg"]
General Comments 0
You need to be logged in to leave comments. Login now