# HG changeset patch # User Pierre-Yves David <pierre-yves.david@octobus.net> # Date 1608689083 -3600 # Wed Dec 23 03:04:43 2020 +0100 # Node ID b6f65d90e8af3aabed7e85304d6ffa3d2dda485b # Parent 3c5a8b13206a53b0a0e8b6138ab5ffdc18fa048a copies-rust: add methods to build and update CopySource Having explicit method with clear semantic help to clarify the code and prepare an update to the underlying documentation without too much disruption. Differential Revision: https://phab.mercurial-scm.org/D9643 diff --git a/rust/hg-core/src/copy_tracing.rs b/rust/hg-core/src/copy_tracing.rs --- a/rust/hg-core/src/copy_tracing.rs +++ b/rust/hg-core/src/copy_tracing.rs @@ -15,7 +15,7 @@ type PathToken = usize; -#[derive(Clone, Debug, PartialEq, Copy)] +#[derive(Clone, Debug, PartialEq)] struct CopySource { /// revision at which the copy information was added rev: Revision, @@ -24,6 +24,42 @@ path: Option<PathToken>, } +impl CopySource { + /// create a new CopySource + /// + /// Use this when no previous copy source existed. + fn new(rev: Revision, path: Option<PathToken>) -> Self { + Self { rev, path } + } + + /// create a new CopySource from merging two others + /// + /// Use this when merging two InternalPathCopies requires active merging of + /// some entries. + fn new_from_merge(rev: Revision, winner: &Self, loser: &Self) -> Self { + Self { + rev, + path: winner.path, + } + } + + /// Update the value of a pre-existing CopySource + /// + /// Use this when recording copy information from parent → child edges + fn overwrite(&mut self, rev: Revision, path: Option<PathToken>) { + self.rev = rev; + self.path = path; + } + + /// Mark pre-existing copy information as "dropped" by a file deletion + /// + /// Use this when recording copy information from parent → child edges + fn mark_delete(&mut self, rev: Revision) { + self.rev = rev; + self.path = None; + } +} + /// maps CopyDestination to Copy Source (+ a "timestamp" for the operation) type InternalPathCopies = OrdMap<PathToken, CopySource>; @@ -521,17 +557,13 @@ // information. See merge_copies_dict for details. match copies.entry(dest) { Entry::Vacant(slot) => { - let ttpc = CopySource { - rev: current_rev, - path: entry, - }; + let ttpc = CopySource::new(current_rev, entry); slot.insert(ttpc); } Entry::Occupied(mut slot) => { - let mut ttpc = slot.get_mut(); + let ttpc = slot.get_mut(); oracle.record_overwrite(ttpc.rev, current_rev); - ttpc.rev = current_rev; - ttpc.path = entry; + ttpc.overwrite(current_rev, entry); } } } @@ -544,8 +576,7 @@ let deleted = path_map.tokenize(deleted_path); copies.entry(deleted).and_modify(|old| { oracle.record_overwrite(old.rev, current_rev); - old.rev = current_rev; - old.path = None; + old.mark_delete(current_rev); }); } } @@ -614,14 +645,22 @@ if overwrite { oracle.record_overwrite(src_minor.rev, current_merge); oracle.record_overwrite(src_major.rev, current_merge); - let path = match pick { - MergePick::Major => src_major.path, - MergePick::Minor => src_minor.path, - MergePick::Any => src_major.path, - }; - let src = CopySource { - rev: current_merge, - path, + let src = match pick { + MergePick::Major => CopySource::new_from_merge( + current_merge, + src_major, + &src_minor, + ), + MergePick::Minor => CopySource::new_from_merge( + current_merge, + &src_minor, + src_major, + ), + MergePick::Any => CopySource::new_from_merge( + current_merge, + src_major, + &src_minor, + ), }; major.insert(dest, src); } else { @@ -649,14 +688,22 @@ if overwrite { oracle.record_overwrite(src_minor.rev, current_merge); oracle.record_overwrite(src_major.rev, current_merge); - let path = match pick { - MergePick::Major => src_minor.path, - MergePick::Minor => src_major.path, - MergePick::Any => src_major.path, - }; - let src = CopySource { - rev: current_merge, - path, + let src = match pick { + MergePick::Major => CopySource::new_from_merge( + current_merge, + &src_major, + src_minor, + ), + MergePick::Minor => CopySource::new_from_merge( + current_merge, + src_minor, + &src_major, + ), + MergePick::Any => CopySource::new_from_merge( + current_merge, + &src_major, + src_minor, + ), }; minor.insert(dest, src); } else { @@ -706,16 +753,22 @@ if overwrite { oracle.record_overwrite(src_minor.rev, current_merge); oracle.record_overwrite(src_major.rev, current_merge); - let path = match pick { - MergePick::Major => src_major.path, - MergePick::Minor => src_minor.path, - // If the two entry are identical, no need to do - // anything (but diff should not have yield them) - MergePick::Any => src_major.path, - }; - let src = CopySource { - rev: current_merge, - path, + let src = match pick { + MergePick::Major => CopySource::new_from_merge( + current_merge, + src_major, + src_minor, + ), + MergePick::Minor => CopySource::new_from_merge( + current_merge, + src_minor, + src_major, + ), + MergePick::Any => CopySource::new_from_merge( + current_merge, + src_major, + src_minor, + ), }; to_minor(dest, &src); to_major(dest, &src);