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