Show More
@@ -1,3 +1,4 b'' | |||||
|
1 | use crate::utils::hg_path::HgPath; | |||
1 | use crate::utils::hg_path::HgPathBuf; |
|
2 | use crate::utils::hg_path::HgPathBuf; | |
2 | use crate::Revision; |
|
3 | use crate::Revision; | |
3 |
|
4 | |||
@@ -36,6 +37,18 b' pub struct ChangedFiles {' | |||||
36 | copied_from_p2: PathCopies, |
|
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 | impl ChangedFiles { |
|
52 | impl ChangedFiles { | |
40 | pub fn new( |
|
53 | pub fn new( | |
41 | removed: HashSet<HgPathBuf>, |
|
54 | removed: HashSet<HgPathBuf>, | |
@@ -62,6 +75,19 b' impl ChangedFiles {' | |||||
62 | copied_from_p2: PathCopies::new(), |
|
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 | /// A struct responsible for answering "is X ancestors of Y" quickly |
|
93 | /// A struct responsible for answering "is X ancestors of Y" quickly | |
@@ -142,15 +168,17 b' pub fn combine_changeset_copies<A: Fn(Re' | |||||
142 | // Creating a new PathCopies for each `rev` ? `children` vertex. |
|
168 | // Creating a new PathCopies for each `rev` ? `children` vertex. | |
143 | let (p1, p2, changes) = rev_info(*child); |
|
169 | let (p1, p2, changes) = rev_info(*child); | |
144 |
|
170 | |||
145 |
let |
|
171 | let parent = if rev == p1 { | |
146 | (1, &changes.copied_from_p1) |
|
172 | 1 | |
147 | } else { |
|
173 | } else { | |
148 | assert_eq!(rev, p2); |
|
174 | assert_eq!(rev, p2); | |
149 | (2, &changes.copied_from_p2) |
|
175 | 2 | |
150 | }; |
|
176 | }; | |
151 | let mut new_copies = copies.clone(); |
|
177 | let mut new_copies = copies.clone(); | |
152 |
|
178 | |||
153 | for (dest, source) in child_copies { |
|
179 | for action in changes.iter_actions(parent) { | |
|
180 | match action { | |||
|
181 | Action::Copied(dest, source) => { | |||
154 | let entry; |
|
182 | let entry; | |
155 | if let Some(v) = copies.get(source) { |
|
183 | if let Some(v) = copies.get(source) { | |
156 | entry = match &v.path { |
|
184 | entry = match &v.path { | |
@@ -160,22 +188,22 b' pub fn combine_changeset_copies<A: Fn(Re' | |||||
160 | } else { |
|
188 | } else { | |
161 | entry = Some(source.to_owned()); |
|
189 | entry = Some(source.to_owned()); | |
162 | } |
|
190 | } | |
163 |
// Each new entry is introduced by the children, we |
|
191 | // Each new entry is introduced by the children, we | |
164 |
// information as we will need it to take |
|
192 | // record this information as we will need it to take | |
165 |
// when merging conflicting copy |
|
193 | // the right decision when merging conflicting copy | |
166 | // merge_copies_dict for details. |
|
194 | // information. See merge_copies_dict for details. | |
167 | let ttpc = TimeStampedPathCopy { |
|
195 | let ttpc = TimeStampedPathCopy { | |
168 | rev: *child, |
|
196 | rev: *child, | |
169 | path: entry, |
|
197 | path: entry, | |
170 | }; |
|
198 | }; | |
171 | new_copies.insert(dest.to_owned(), ttpc); |
|
199 | new_copies.insert(dest.to_owned(), ttpc); | |
172 | } |
|
200 | } | |
173 |
|
201 | Action::Removed(f) => { | ||
174 | // We must drop copy information for removed file. |
|
202 | // We must drop copy information for removed file. | |
175 | // |
|
203 | // | |
176 |
// We need to explicitly record them as dropped to |
|
204 | // We need to explicitly record them as dropped to | |
177 |
// information when merging two |
|
205 | // propagate this information when merging two | |
178 | for f in changes.removed.iter() { |
|
206 | // TimeStampedPathCopies object. | |
179 | if new_copies.contains_key(f.as_ref()) { |
|
207 | if new_copies.contains_key(f.as_ref()) { | |
180 | let ttpc = TimeStampedPathCopy { |
|
208 | let ttpc = TimeStampedPathCopy { | |
181 | rev: *child, |
|
209 | rev: *child, | |
@@ -184,6 +212,8 b' pub fn combine_changeset_copies<A: Fn(Re' | |||||
184 | new_copies.insert(f.to_owned(), ttpc); |
|
212 | new_copies.insert(f.to_owned(), ttpc); | |
185 | } |
|
213 | } | |
186 | } |
|
214 | } | |
|
215 | } | |||
|
216 | } | |||
187 |
|
217 | |||
188 | // Merge has two parents needs to combines their copy information. |
|
218 | // Merge has two parents needs to combines their copy information. | |
189 | // |
|
219 | // |
General Comments 0
You need to be logged in to leave comments.
Login now