Show More
@@ -1,3 +1,4 b'' | |||
|
1 | use crate::utils::hg_path::HgPath; | |
|
1 | 2 | use crate::utils::hg_path::HgPathBuf; |
|
2 | 3 | use crate::Revision; |
|
3 | 4 | |
@@ -36,6 +37,18 b' pub struct ChangedFiles {' | |||
|
36 | 37 | copied_from_p2: PathCopies, |
|
37 | 38 | } |
|
38 | 39 | |
|
40 | /// Represent active changes that affect the copy tracing. | |
|
41 | enum Action<'a> { | |
|
42 | /// The parent ? children edge is removing a file | |
|
43 | /// | |
|
44 | /// (actually, this could be the edge from the other parent, but it does | |
|
45 | /// not matters) | |
|
46 | Removed(&'a HgPath), | |
|
47 | /// The parent ? children edge introduce copy information between (dest, | |
|
48 | /// source) | |
|
49 | Copied(&'a HgPath, &'a HgPath), | |
|
50 | } | |
|
51 | ||
|
39 | 52 | impl ChangedFiles { |
|
40 | 53 | pub fn new( |
|
41 | 54 | removed: HashSet<HgPathBuf>, |
@@ -62,6 +75,19 b' impl ChangedFiles {' | |||
|
62 | 75 | copied_from_p2: PathCopies::new(), |
|
63 | 76 | } |
|
64 | 77 | } |
|
78 | ||
|
79 | /// Return an iterator over all the `Action` in this instance. | |
|
80 | fn iter_actions(&self, parent: usize) -> impl Iterator<Item = Action> { | |
|
81 | let copies_iter = match parent { | |
|
82 | 1 => self.copied_from_p1.iter(), | |
|
83 | 2 => self.copied_from_p2.iter(), | |
|
84 | _ => unreachable!(), | |
|
85 | }; | |
|
86 | let remove_iter = self.removed.iter(); | |
|
87 | let copies_iter = copies_iter.map(|(x, y)| Action::Copied(x, y)); | |
|
88 | let remove_iter = remove_iter.map(|x| Action::Removed(x)); | |
|
89 | copies_iter.chain(remove_iter) | |
|
90 | } | |
|
65 | 91 | } |
|
66 | 92 | |
|
67 | 93 | /// A struct responsible for answering "is X ancestors of Y" quickly |
@@ -142,46 +168,50 b' pub fn combine_changeset_copies<A: Fn(Re' | |||
|
142 | 168 | // Creating a new PathCopies for each `rev` ? `children` vertex. |
|
143 | 169 | let (p1, p2, changes) = rev_info(*child); |
|
144 | 170 | |
|
145 |
let |
|
|
146 | (1, &changes.copied_from_p1) | |
|
171 | let parent = if rev == p1 { | |
|
172 | 1 | |
|
147 | 173 | } else { |
|
148 | 174 | assert_eq!(rev, p2); |
|
149 | (2, &changes.copied_from_p2) | |
|
175 | 2 | |
|
150 | 176 | }; |
|
151 | 177 | let mut new_copies = copies.clone(); |
|
152 | 178 | |
|
153 | for (dest, source) in child_copies { | |
|
154 |
|
|
|
155 |
|
|
|
156 |
entry |
|
|
157 | Some(path) => Some((*(path)).to_owned()), | |
|
158 | None => Some(source.to_owned()), | |
|
179 | for action in changes.iter_actions(parent) { | |
|
180 | match action { | |
|
181 | Action::Copied(dest, source) => { | |
|
182 | let entry; | |
|
183 | if let Some(v) = copies.get(source) { | |
|
184 | entry = match &v.path { | |
|
185 | Some(path) => Some((*(path)).to_owned()), | |
|
186 | None => Some(source.to_owned()), | |
|
187 | } | |
|
188 | } else { | |
|
189 | entry = Some(source.to_owned()); | |
|
190 | } | |
|
191 | // Each new entry is introduced by the children, we | |
|
192 | // record this information as we will need it to take | |
|
193 | // the right decision when merging conflicting copy | |
|
194 | // information. See merge_copies_dict for details. | |
|
195 | let ttpc = TimeStampedPathCopy { | |
|
196 | rev: *child, | |
|
197 | path: entry, | |
|
198 | }; | |
|
199 | new_copies.insert(dest.to_owned(), ttpc); | |
|
159 | 200 | } |
|
160 |
|
|
|
161 | entry = Some(source.to_owned()); | |
|
162 |
|
|
|
163 | // Each new entry is introduced by the children, we record this | |
|
164 | // information as we will need it to take the right decision | |
|
165 | // when merging conflicting copy information. See | |
|
166 | // merge_copies_dict for details. | |
|
167 | let ttpc = TimeStampedPathCopy { | |
|
168 | rev: *child, | |
|
169 |
path: |
|
|
170 | }; | |
|
171 |
new_copies.insert( |
|
|
172 | } | |
|
173 | ||
|
174 | // We must drop copy information for removed file. | |
|
175 | // | |
|
176 | // We need to explicitly record them as dropped to propagate this | |
|
177 | // information when merging two TimeStampedPathCopies object. | |
|
178 | for f in changes.removed.iter() { | |
|
179 | if new_copies.contains_key(f.as_ref()) { | |
|
180 | let ttpc = TimeStampedPathCopy { | |
|
181 | rev: *child, | |
|
182 | path: None, | |
|
183 | }; | |
|
184 | new_copies.insert(f.to_owned(), ttpc); | |
|
201 | Action::Removed(f) => { | |
|
202 | // We must drop copy information for removed file. | |
|
203 | // | |
|
204 | // We need to explicitly record them as dropped to | |
|
205 | // propagate this information when merging two | |
|
206 | // TimeStampedPathCopies object. | |
|
207 | if new_copies.contains_key(f.as_ref()) { | |
|
208 | let ttpc = TimeStampedPathCopy { | |
|
209 | rev: *child, | |
|
210 | path: None, | |
|
211 | }; | |
|
212 | new_copies.insert(f.to_owned(), ttpc); | |
|
213 | } | |
|
214 | } | |
|
185 | 215 | } |
|
186 | 216 | } |
|
187 | 217 |
General Comments 0
You need to be logged in to leave comments.
Login now