rust/hg-core/src/copy_tracing.rs
changeset 46059 dacb771f6dd2
parent 46058 12192fdbf3ac
child 46125 61afe6215aef
--- a/rust/hg-core/src/copy_tracing.rs	Fri Nov 20 14:03:40 2020 +0100
+++ b/rust/hg-core/src/copy_tracing.rs	Fri Nov 20 14:17:08 2020 +0100
@@ -360,46 +360,8 @@
                 assert_eq!(rev, p2);
                 Parent::SecondParent
             };
-            let mut new_copies = copies.clone();
-
-            for action in changes.iter_actions(parent) {
-                match action {
-                    Action::Copied(dest, source) => {
-                        let entry;
-                        if let Some(v) = copies.get(source) {
-                            entry = match &v.path {
-                                Some(path) => Some((*(path)).to_owned()),
-                                None => Some(source.to_owned()),
-                            }
-                        } else {
-                            entry = Some(source.to_owned());
-                        }
-                        // Each new entry is introduced by the children, we
-                        // record this information as we will need it to take
-                        // the right decision when merging conflicting copy
-                        // information. See merge_copies_dict for details.
-                        let ttpc = TimeStampedPathCopy {
-                            rev: *child,
-                            path: entry,
-                        };
-                        new_copies.insert(dest.to_owned(), ttpc);
-                    }
-                    Action::Removed(f) => {
-                        // We must drop copy information for removed file.
-                        //
-                        // We need to explicitly record them as dropped to
-                        // propagate this information when merging two
-                        // TimeStampedPathCopies object.
-                        if new_copies.contains_key(f.as_ref()) {
-                            let ttpc = TimeStampedPathCopy {
-                                rev: *child,
-                                path: None,
-                            };
-                            new_copies.insert(f.to_owned(), ttpc);
-                        }
-                    }
-                }
-            }
+            let new_copies =
+                add_from_changes(&copies, &changes, parent, *child);
 
             // Merge has two parents needs to combines their copy information.
             //
@@ -441,6 +403,56 @@
     result
 }
 
+/// Combine ChangedFiles with some existing PathCopies information and return
+/// the result
+fn add_from_changes(
+    base_copies: &TimeStampedPathCopies,
+    changes: &ChangedFiles,
+    parent: Parent,
+    current_rev: Revision,
+) -> TimeStampedPathCopies {
+    let mut copies = base_copies.clone();
+    for action in changes.iter_actions(parent) {
+        match action {
+            Action::Copied(dest, source) => {
+                let entry;
+                if let Some(v) = base_copies.get(source) {
+                    entry = match &v.path {
+                        Some(path) => Some((*(path)).to_owned()),
+                        None => Some(source.to_owned()),
+                    }
+                } else {
+                    entry = Some(source.to_owned());
+                }
+                // Each new entry is introduced by the children, we
+                // record this information as we will need it to take
+                // the right decision when merging conflicting copy
+                // information. See merge_copies_dict for details.
+                let ttpc = TimeStampedPathCopy {
+                    rev: current_rev,
+                    path: entry,
+                };
+                copies.insert(dest.to_owned(), ttpc);
+            }
+            Action::Removed(f) => {
+                // We must drop copy information for removed file.
+                //
+                // We need to explicitly record them as dropped to
+                // propagate this information when merging two
+                // TimeStampedPathCopies object.
+                if copies.contains_key(f.as_ref()) {
+                    let ttpc = TimeStampedPathCopy {
+                        rev: current_rev,
+                        path: None,
+                    };
+                    copies.insert(f.to_owned(), ttpc);
+                }
+            }
+        }
+    }
+    copies
+}
+
 /// merge two copies-mapping together, minor and major
 ///
 /// In case of conflict, value from "major" will be picked, unless in some