Show More
@@ -9,6 +9,7 b' use im_rc::ordmap::OrdMap;' | |||
|
9 | 9 | |
|
10 | 10 | use std::cmp::Ordering; |
|
11 | 11 | use std::collections::HashMap; |
|
12 | use std::collections::HashSet; | |
|
12 | 13 | use std::convert::TryInto; |
|
13 | 14 | |
|
14 | 15 | pub type PathCopies = HashMap<HgPathBuf, HgPathBuf>; |
@@ -22,6 +23,9 b' struct CopySource {' | |||
|
22 | 23 | /// the copy source, (Set to None in case of deletion of the associated |
|
23 | 24 | /// key) |
|
24 | 25 | path: Option<PathToken>, |
|
26 | /// a set of previous `CopySource.rev` value directly or indirectly | |
|
27 | /// overwritten by this one. | |
|
28 | overwritten: HashSet<Revision>, | |
|
25 | 29 | } |
|
26 | 30 | |
|
27 | 31 | impl CopySource { |
@@ -29,7 +33,11 b' impl CopySource {' | |||
|
29 | 33 | /// |
|
30 | 34 | /// Use this when no previous copy source existed. |
|
31 | 35 | fn new(rev: Revision, path: Option<PathToken>) -> Self { |
|
32 |
Self { |
|
|
36 | Self { | |
|
37 | rev, | |
|
38 | path, | |
|
39 | overwritten: HashSet::new(), | |
|
40 | } | |
|
33 | 41 | } |
|
34 | 42 | |
|
35 | 43 | /// create a new CopySource from merging two others |
@@ -37,9 +45,15 b' impl CopySource {' | |||
|
37 | 45 | /// Use this when merging two InternalPathCopies requires active merging of |
|
38 | 46 | /// some entries. |
|
39 | 47 | fn new_from_merge(rev: Revision, winner: &Self, loser: &Self) -> Self { |
|
48 | let mut overwritten = HashSet::new(); | |
|
49 | overwritten.extend(winner.overwritten.iter().copied()); | |
|
50 | overwritten.extend(loser.overwritten.iter().copied()); | |
|
51 | overwritten.insert(winner.rev); | |
|
52 | overwritten.insert(loser.rev); | |
|
40 | 53 | Self { |
|
41 | 54 | rev, |
|
42 | 55 | path: winner.path, |
|
56 | overwritten: overwritten, | |
|
43 | 57 | } |
|
44 | 58 | } |
|
45 | 59 | |
@@ -47,6 +61,7 b' impl CopySource {' | |||
|
47 | 61 | /// |
|
48 | 62 | /// Use this when recording copy information from parent → child edges |
|
49 | 63 | fn overwrite(&mut self, rev: Revision, path: Option<PathToken>) { |
|
64 | self.overwritten.insert(self.rev); | |
|
50 | 65 | self.rev = rev; |
|
51 | 66 | self.path = path; |
|
52 | 67 | } |
@@ -55,9 +70,14 b' impl CopySource {' | |||
|
55 | 70 | /// |
|
56 | 71 | /// Use this when recording copy information from parent → child edges |
|
57 | 72 | fn mark_delete(&mut self, rev: Revision) { |
|
73 | self.overwritten.insert(self.rev); | |
|
58 | 74 | self.rev = rev; |
|
59 | 75 | self.path = None; |
|
60 | 76 | } |
|
77 | ||
|
78 | fn is_overwritten_by(&self, other: &Self) -> bool { | |
|
79 | other.overwritten.contains(&self.rev) | |
|
80 | } | |
|
61 | 81 | } |
|
62 | 82 | |
|
63 | 83 | /// maps CopyDestination to Copy Source (+ a "timestamp" for the operation) |
@@ -834,8 +854,12 b' fn compare_value<A: Fn(Revision, Revisio' | |||
|
834 | 854 | if src_major.path.is_none() { |
|
835 | 855 | // We cannot get different copy information for both p1 and p2 |
|
836 | 856 | // from the same revision. Unless this was a |
|
837 | // deletion | |
|
838 | (MergePick::Any, false) | |
|
857 | // deletion. | |
|
858 | // | |
|
859 | // However the deletion might come over different data on each | |
|
860 | // branch. | |
|
861 | let need_over = src_major.overwritten != src_minor.overwritten; | |
|
862 | (MergePick::Any, need_over) | |
|
839 | 863 | } else { |
|
840 | 864 | unreachable!(); |
|
841 | 865 | } |
@@ -852,10 +876,11 b' fn compare_value<A: Fn(Revision, Revisio' | |||
|
852 | 876 | // we have the same value, but from other source; |
|
853 | 877 | if src_major.rev == src_minor.rev { |
|
854 | 878 | // If the two entry are identical, they are both valid |
|
879 | debug_assert!(src_minor.overwritten == src_minor.overwritten); | |
|
855 | 880 | (MergePick::Any, false) |
|
856 |
} else if |
|
|
881 | } else if src_major.is_overwritten_by(src_minor) { | |
|
857 | 882 | (MergePick::Minor, false) |
|
858 |
} else if |
|
|
883 | } else if src_minor.is_overwritten_by(src_major) { | |
|
859 | 884 | (MergePick::Major, false) |
|
860 | 885 | } else { |
|
861 | 886 | (MergePick::Any, true) |
@@ -884,7 +909,7 b' fn compare_value<A: Fn(Revision, Revisio' | |||
|
884 | 909 | // salvaged by the merge, unconditionnaly preserve the |
|
885 | 910 | // major side. |
|
886 | 911 | (MergePick::Major, true) |
|
887 |
} else if |
|
|
912 | } else if src_minor.is_overwritten_by(src_major) { | |
|
888 | 913 | // The information from the minor version are strictly older than |
|
889 | 914 | // the major version |
|
890 | 915 | if action == MergeCase::Merged { |
@@ -898,7 +923,7 b' fn compare_value<A: Fn(Revision, Revisio' | |||
|
898 | 923 | // No activity on the minor branch, pick the newer one. |
|
899 | 924 | (MergePick::Major, false) |
|
900 | 925 | } |
|
901 |
} else if |
|
|
926 | } else if src_major.is_overwritten_by(src_minor) { | |
|
902 | 927 | if action == MergeCase::Merged { |
|
903 | 928 | // If the file was actively merged, its means some non-copy |
|
904 | 929 | // activity happened on the other branch. It |
General Comments 0
You need to be logged in to leave comments.
Login now