rust/hg-core/src/copy_tracing.rs
author Sandu Turcan <idlsoft@gmail.com>
Tue, 03 May 2022 21:44:30 -0400
branchstable
changeset 49241 6b10151b9621
parent 46658 fa21633af201
child 49916 321e2b7bc95c
permissions -rw-r--r--
narrow_widen_acl: enforce narrowacl in narrow_widen (SEC) Reviewer note: this was sent by the author as a simple bugfix, but can be considered a security patch, since it allows users to access things outside of the ACL, hence the (SEC) prefix. However, this affects the `narrow` extention which is still marked as experimental and has relatively few users aside from large companies with their own security layers on top from what we can gather. We feel (Alphare: or at least, I feel) like pinging the packaging list is enough in this case.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46658
fa21633af201 copies-rust: add a macro-based unit-testing framework
Simon Sapin <simon.sapin@octobus.net>
parents: 46657
diff changeset
     1
#[cfg(test)]
fa21633af201 copies-rust: add a macro-based unit-testing framework
Simon Sapin <simon.sapin@octobus.net>
parents: 46657
diff changeset
     2
#[macro_use]
fa21633af201 copies-rust: add a macro-based unit-testing framework
Simon Sapin <simon.sapin@octobus.net>
parents: 46657
diff changeset
     3
mod tests_support;
fa21633af201 copies-rust: add a macro-based unit-testing framework
Simon Sapin <simon.sapin@octobus.net>
parents: 46657
diff changeset
     4
fa21633af201 copies-rust: add a macro-based unit-testing framework
Simon Sapin <simon.sapin@octobus.net>
parents: 46657
diff changeset
     5
#[cfg(test)]
fa21633af201 copies-rust: add a macro-based unit-testing framework
Simon Sapin <simon.sapin@octobus.net>
parents: 46657
diff changeset
     6
mod tests;
fa21633af201 copies-rust: add a macro-based unit-testing framework
Simon Sapin <simon.sapin@octobus.net>
parents: 46657
diff changeset
     7
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
     8
use crate::utils::hg_path::HgPath;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     9
use crate::utils::hg_path::HgPathBuf;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    10
use crate::Revision;
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
    11
use crate::NULL_REVISION;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    12
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
    13
use bytes_cast::{unaligned, BytesCast};
46153
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
    14
use im_rc::ordmap::Entry;
45963
0d99778af68a copies-rust: use immutable "OrdMap" to store copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45944
diff changeset
    15
use im_rc::ordmap::OrdMap;
46585
60b2b7ecf9cb copies-rust: use imrs::OrdSet instead of imrs::HashSet
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46584
diff changeset
    16
use im_rc::OrdSet;
45963
0d99778af68a copies-rust: use immutable "OrdMap" to store copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45944
diff changeset
    17
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    18
use std::cmp::Ordering;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    19
use std::collections::HashMap;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    20
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    21
pub type PathCopies = HashMap<HgPathBuf, HgPathBuf>;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    22
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
    23
type PathToken = usize;
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
    24
46582
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
    25
#[derive(Clone, Debug)]
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
    26
struct CopySource {
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    27
    /// revision at which the copy information was added
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    28
    rev: Revision,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    29
    /// the copy source, (Set to None in case of deletion of the associated
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    30
    /// key)
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
    31
    path: Option<PathToken>,
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    32
    /// a set of previous `CopySource.rev` value directly or indirectly
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    33
    /// overwritten by this one.
46585
60b2b7ecf9cb copies-rust: use imrs::OrdSet instead of imrs::HashSet
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46584
diff changeset
    34
    overwritten: OrdSet<Revision>,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    35
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    36
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    37
impl CopySource {
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    38
    /// create a new CopySource
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    39
    ///
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    40
    /// Use this when no previous copy source existed.
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    41
    fn new(rev: Revision, path: Option<PathToken>) -> Self {
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    42
        Self {
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    43
            rev,
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    44
            path,
46585
60b2b7ecf9cb copies-rust: use imrs::OrdSet instead of imrs::HashSet
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46584
diff changeset
    45
            overwritten: OrdSet::new(),
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    46
        }
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    47
    }
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    48
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    49
    /// create a new CopySource from merging two others
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    50
    ///
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    51
    /// Use this when merging two InternalPathCopies requires active merging of
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    52
    /// some entries.
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    53
    fn new_from_merge(rev: Revision, winner: &Self, loser: &Self) -> Self {
46585
60b2b7ecf9cb copies-rust: use imrs::OrdSet instead of imrs::HashSet
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46584
diff changeset
    54
        let mut overwritten = OrdSet::new();
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    55
        overwritten.extend(winner.overwritten.iter().copied());
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    56
        overwritten.extend(loser.overwritten.iter().copied());
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    57
        overwritten.insert(winner.rev);
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    58
        overwritten.insert(loser.rev);
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    59
        Self {
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    60
            rev,
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    61
            path: winner.path,
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    62
            overwritten: overwritten,
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    63
        }
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    64
    }
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    65
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    66
    /// Update the value of a pre-existing CopySource
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    67
    ///
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    68
    /// Use this when recording copy information from  parent → child edges
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    69
    fn overwrite(&mut self, rev: Revision, path: Option<PathToken>) {
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    70
        self.overwritten.insert(self.rev);
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    71
        self.rev = rev;
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    72
        self.path = path;
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    73
    }
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    74
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    75
    /// Mark pre-existing copy information as "dropped" by a file deletion
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    76
    ///
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    77
    /// Use this when recording copy information from  parent → child edges
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    78
    fn mark_delete(&mut self, rev: Revision) {
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    79
        self.overwritten.insert(self.rev);
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    80
        self.rev = rev;
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    81
        self.path = None;
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    82
    }
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    83
46581
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    84
    /// Mark pre-existing copy information as "dropped" by a file deletion
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    85
    ///
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    86
    /// Use this when recording copy information from  parent → child edges
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    87
    fn mark_delete_with_pair(&mut self, rev: Revision, other: &Self) {
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    88
        self.overwritten.insert(self.rev);
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    89
        if other.rev != rev {
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    90
            self.overwritten.insert(other.rev);
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    91
        }
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    92
        self.overwritten.extend(other.overwritten.iter().copied());
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    93
        self.rev = rev;
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    94
        self.path = None;
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    95
    }
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    96
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    97
    fn is_overwritten_by(&self, other: &Self) -> bool {
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    98
        other.overwritten.contains(&self.rev)
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    99
    }
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
   100
}
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
   101
46582
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   102
// For the same "dest", content generated for a given revision will always be
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   103
// the same.
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   104
impl PartialEq for CopySource {
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   105
    fn eq(&self, other: &Self) -> bool {
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   106
        #[cfg(debug_assertions)]
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   107
        {
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   108
            if self.rev == other.rev {
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   109
                debug_assert!(self.path == other.path);
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   110
                debug_assert!(self.overwritten == other.overwritten);
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   111
            }
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   112
        }
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   113
        self.rev == other.rev
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   114
    }
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   115
}
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   116
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   117
/// maps CopyDestination to Copy Source (+ a "timestamp" for the operation)
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   118
type InternalPathCopies = OrdMap<PathToken, CopySource>;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   119
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   120
/// Represent active changes that affect the copy tracing.
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   121
enum Action<'a> {
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   122
    /// The parent ? children edge is removing a file
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   123
    ///
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   124
    /// (actually, this could be the edge from the other parent, but it does
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   125
    /// not matters)
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   126
    Removed(&'a HgPath),
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   127
    /// The parent ? children edge introduce copy information between (dest,
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   128
    /// source)
46578
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   129
    CopiedFromP1(&'a HgPath, &'a HgPath),
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   130
    CopiedFromP2(&'a HgPath, &'a HgPath),
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   131
}
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   132
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   133
/// This express the possible "special" case we can get in a merge
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   134
///
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   135
/// See mercurial/metadata.py for details on these values.
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   136
#[derive(PartialEq)]
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   137
enum MergeCase {
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   138
    /// Merged: file had history on both side that needed to be merged
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   139
    Merged,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   140
    /// Salvaged: file was candidate for deletion, but survived the merge
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   141
    Salvaged,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   142
    /// Normal: Not one of the two cases above
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   143
    Normal,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   144
}
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   145
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   146
const COPY_MASK: u8 = 3;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   147
const P1_COPY: u8 = 2;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   148
const P2_COPY: u8 = 3;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   149
const ACTION_MASK: u8 = 28;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   150
const REMOVED: u8 = 12;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   151
const MERGED: u8 = 8;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   152
const SALVAGED: u8 = 16;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   153
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   154
#[derive(BytesCast)]
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   155
#[repr(C)]
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   156
struct ChangedFilesIndexEntry {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   157
    flags: u8,
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   158
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   159
    /// Only the end position is stored. The start is at the end of the
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   160
    /// previous entry.
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   161
    destination_path_end_position: unaligned::U32Be,
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   162
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   163
    source_index_entry_position: unaligned::U32Be,
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   164
}
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   165
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   166
fn _static_assert_size_of() {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   167
    let _ = std::mem::transmute::<ChangedFilesIndexEntry, [u8; 9]>;
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   168
}
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   169
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   170
/// Represents the files affected by a changeset.
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   171
///
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   172
/// This holds a subset of `mercurial.metadata.ChangingFiles` as we do not need
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   173
/// all the data categories tracked by it.
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   174
pub struct ChangedFiles<'a> {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   175
    index: &'a [ChangedFilesIndexEntry],
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   176
    paths: &'a [u8],
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   177
}
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   178
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   179
impl<'a> ChangedFiles<'a> {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   180
    pub fn new(data: &'a [u8]) -> Self {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   181
        let (header, rest) = unaligned::U32Be::from_bytes(data).unwrap();
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   182
        let nb_index_entries = header.get() as usize;
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   183
        let (index, paths) =
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   184
            ChangedFilesIndexEntry::slice_from_bytes(rest, nb_index_entries)
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   185
                .unwrap();
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   186
        Self { index, paths }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   187
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   188
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   189
    pub fn new_empty() -> Self {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   190
        ChangedFiles {
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   191
            index: &[],
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   192
            paths: &[],
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   193
        }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   194
    }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   195
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   196
    /// Internal function to return the filename of the entry at a given index
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   197
    fn path(&self, idx: usize) -> &HgPath {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   198
        let start = if idx == 0 {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   199
            0
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   200
        } else {
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   201
            self.index[idx - 1].destination_path_end_position.get() as usize
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   202
        };
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   203
        let end = self.index[idx].destination_path_end_position.get() as usize;
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   204
        HgPath::new(&self.paths[start..end])
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   205
    }
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   206
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   207
    /// Return an iterator over all the `Action` in this instance.
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   208
    fn iter_actions(&self) -> impl Iterator<Item = Action> {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   209
        self.index.iter().enumerate().flat_map(move |(idx, entry)| {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   210
            let path = self.path(idx);
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   211
            if (entry.flags & ACTION_MASK) == REMOVED {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   212
                Some(Action::Removed(path))
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   213
            } else if (entry.flags & COPY_MASK) == P1_COPY {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   214
                let source_idx =
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   215
                    entry.source_index_entry_position.get() as usize;
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   216
                Some(Action::CopiedFromP1(path, self.path(source_idx)))
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   217
            } else if (entry.flags & COPY_MASK) == P2_COPY {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   218
                let source_idx =
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   219
                    entry.source_index_entry_position.get() as usize;
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   220
                Some(Action::CopiedFromP2(path, self.path(source_idx)))
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   221
            } else {
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   222
                None
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   223
            }
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   224
        })
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   225
    }
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   226
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   227
    /// return the MergeCase value associated with a filename
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   228
    fn get_merge_case(&self, path: &HgPath) -> MergeCase {
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   229
        if self.index.is_empty() {
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   230
            return MergeCase::Normal;
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   231
        }
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   232
        let mut low_part = 0;
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   233
        let mut high_part = self.index.len();
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   234
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   235
        while low_part < high_part {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   236
            let cursor = (low_part + high_part - 1) / 2;
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   237
            match path.cmp(self.path(cursor)) {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   238
                Ordering::Less => low_part = cursor + 1,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   239
                Ordering::Greater => high_part = cursor,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   240
                Ordering::Equal => {
46657
f977a065c7c2 copies-rust: rewrite ChangedFiles binary parsing
Simon Sapin <simon.sapin@octobus.net>
parents: 46619
diff changeset
   241
                    return match self.index[cursor].flags & ACTION_MASK {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   242
                        MERGED => MergeCase::Merged,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   243
                        SALVAGED => MergeCase::Salvaged,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   244
                        _ => MergeCase::Normal,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   245
                    };
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   246
                }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   247
            }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   248
        }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   249
        MergeCase::Normal
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   250
    }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   251
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   252
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   253
/// A small "tokenizer" responsible of turning full HgPath into lighter
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   254
/// PathToken
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   255
///
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   256
/// Dealing with small object, like integer is much faster, so HgPath input are
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   257
/// turned into integer "PathToken" and converted back in the end.
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   258
#[derive(Clone, Debug, Default)]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   259
struct TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   260
    token: HashMap<HgPathBuf, PathToken>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   261
    path: Vec<HgPathBuf>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   262
}
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   263
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   264
impl TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   265
    fn tokenize(&mut self, path: &HgPath) -> PathToken {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   266
        match self.token.get(path) {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   267
            Some(a) => *a,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   268
            None => {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   269
                let a = self.token.len();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   270
                let buf = path.to_owned();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   271
                self.path.push(buf.clone());
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   272
                self.token.insert(buf, a);
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   273
                a
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   274
            }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   275
        }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   276
    }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   277
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   278
    fn untokenize(&self, token: PathToken) -> &HgPathBuf {
46619
f2fc34e88238 copies-rust: remove an unnecessary format!() inside assert!()
Martin von Zweigbergk <martinvonz@google.com>
parents: 46612
diff changeset
   279
        assert!(token < self.path.len(), "Unknown token: {}", token);
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   280
        &self.path[token]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   281
    }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   282
}
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   283
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   284
/// Same as mercurial.copies._combine_changeset_copies, but in Rust.
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   285
pub struct CombineChangesetCopies {
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   286
    all_copies: HashMap<Revision, InternalPathCopies>,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   287
    path_map: TwoWayPathMap,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   288
    children_count: HashMap<Revision, usize>,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   289
}
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   290
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   291
impl CombineChangesetCopies {
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   292
    pub fn new(children_count: HashMap<Revision, usize>) -> Self {
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   293
        Self {
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   294
            all_copies: HashMap::new(),
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   295
            path_map: TwoWayPathMap::default(),
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   296
            children_count,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   297
        }
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   298
    }
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   299
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   300
    /// Combined the given `changes` data specific to `rev` with the data
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   301
    /// previously given for its parents (and transitively, its ancestors).
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   302
    pub fn add_revision(
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   303
        &mut self,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   304
        rev: Revision,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   305
        p1: Revision,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   306
        p2: Revision,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   307
        changes: ChangedFiles<'_>,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   308
    ) {
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   309
        self.add_revision_inner(rev, p1, p2, changes.iter_actions(), |path| {
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   310
            changes.get_merge_case(path)
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   311
        })
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   312
    }
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   313
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   314
    /// Separated out from `add_revsion` so that unit tests can call this
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   315
    /// without synthetizing a `ChangedFiles` in binary format.
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   316
    fn add_revision_inner<'a>(
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   317
        &mut self,
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   318
        rev: Revision,
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   319
        p1: Revision,
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   320
        p2: Revision,
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   321
        copy_actions: impl Iterator<Item = Action<'a>>,
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   322
        get_merge_case: impl Fn(&HgPath) -> MergeCase + Copy,
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   323
    ) {
46575
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   324
        // Retrieve data computed in a previous iteration
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   325
        let p1_copies = match p1 {
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   326
            NULL_REVISION => None,
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   327
            _ => get_and_clean_parent_copies(
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   328
                &mut self.all_copies,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   329
                &mut self.children_count,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   330
                p1,
46575
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   331
            ), // will be None if the vertex is not to be traversed
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   332
        };
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   333
        let p2_copies = match p2 {
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   334
            NULL_REVISION => None,
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   335
            _ => get_and_clean_parent_copies(
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   336
                &mut self.all_copies,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   337
                &mut self.children_count,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   338
                p2,
46575
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   339
            ), // will be None if the vertex is not to be traversed
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   340
        };
46576
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   341
        // combine it with data for that revision
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   342
        let (p1_copies, p2_copies) = chain_changes(
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   343
            &mut self.path_map,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   344
            p1_copies,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   345
            p2_copies,
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   346
            copy_actions,
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   347
            rev,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   348
        );
46576
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   349
        let copies = match (p1_copies, p2_copies) {
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   350
            (None, None) => None,
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   351
            (c, None) => c,
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   352
            (None, c) => c,
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   353
            (Some(p1_copies), Some(p2_copies)) => Some(merge_copies_dict(
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   354
                &self.path_map,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   355
                rev,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   356
                p2_copies,
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   357
                p1_copies,
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   358
                get_merge_case,
46576
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   359
            )),
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   360
        };
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   361
        if let Some(c) = copies {
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   362
            self.all_copies.insert(rev, c);
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   363
        }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   364
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   365
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   366
    /// Drop intermediate data (such as which revision a copy was from) and
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   367
    /// return the final mapping.
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   368
    pub fn finish(mut self, target_rev: Revision) -> PathCopies {
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   369
        let tt_result = self
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   370
            .all_copies
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   371
            .remove(&target_rev)
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   372
            .expect("target revision was not processed");
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   373
        let mut result = PathCopies::default();
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   374
        for (dest, tt_source) in tt_result {
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   375
            if let Some(path) = tt_source.path {
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   376
                let path_dest = self.path_map.untokenize(dest).to_owned();
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   377
                let path_path = self.path_map.untokenize(path).to_owned();
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   378
                result.insert(path_dest, path_path);
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   379
            }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   380
        }
46587
cb4b0b0c6de4 copies-rust: split up combine_changeset_copies function into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46586
diff changeset
   381
        result
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   382
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   383
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   384
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   385
/// fetch previous computed information
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   386
///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   387
/// If no other children are expected to need this information, we drop it from
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   388
/// the cache.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   389
///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   390
/// If parent is not part of the set we are expected to walk, return None.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   391
fn get_and_clean_parent_copies(
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   392
    all_copies: &mut HashMap<Revision, InternalPathCopies>,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   393
    children_count: &mut HashMap<Revision, usize>,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   394
    parent_rev: Revision,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   395
) -> Option<InternalPathCopies> {
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   396
    let count = children_count.get_mut(&parent_rev)?;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   397
    *count -= 1;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   398
    if *count == 0 {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   399
        match all_copies.remove(&parent_rev) {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   400
            Some(c) => Some(c),
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   401
            None => Some(InternalPathCopies::default()),
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   402
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   403
    } else {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   404
        match all_copies.get(&parent_rev) {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   405
            Some(c) => Some(c.clone()),
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   406
            None => Some(InternalPathCopies::default()),
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   407
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   408
    }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   409
}
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   410
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   411
/// Combine ChangedFiles with some existing PathCopies information and return
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   412
/// the result
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   413
fn chain_changes<'a>(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   414
    path_map: &mut TwoWayPathMap,
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   415
    base_p1_copies: Option<InternalPathCopies>,
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   416
    base_p2_copies: Option<InternalPathCopies>,
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   417
    copy_actions: impl Iterator<Item = Action<'a>>,
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   418
    current_rev: Revision,
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   419
) -> (Option<InternalPathCopies>, Option<InternalPathCopies>) {
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   420
    // Fast path the "nothing to do" case.
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   421
    if let (None, None) = (&base_p1_copies, &base_p2_copies) {
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   422
        return (None, None);
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   423
    }
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   424
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   425
    let mut p1_copies = base_p1_copies.clone();
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   426
    let mut p2_copies = base_p2_copies.clone();
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   427
    for action in copy_actions {
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   428
        match action {
46578
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   429
            Action::CopiedFromP1(path_dest, path_source) => {
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   430
                match &mut p1_copies {
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   431
                    None => (), // This is not a vertex we should proceed.
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   432
                    Some(copies) => add_one_copy(
46578
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   433
                        current_rev,
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   434
                        path_map,
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   435
                        copies,
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   436
                        base_p1_copies.as_ref().unwrap(),
46578
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   437
                        path_dest,
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   438
                        path_source,
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   439
                    ),
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   440
                }
46578
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   441
            }
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   442
            Action::CopiedFromP2(path_dest, path_source) => {
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   443
                match &mut p2_copies {
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   444
                    None => (), // This is not a vertex we should proceed.
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   445
                    Some(copies) => add_one_copy(
46578
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   446
                        current_rev,
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   447
                        path_map,
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   448
                        copies,
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   449
                        base_p2_copies.as_ref().unwrap(),
46578
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   450
                        path_dest,
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   451
                        path_source,
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   452
                    ),
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   453
                }
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   454
            }
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   455
            Action::Removed(deleted_path) => {
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   456
                // We must drop copy information for removed file.
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   457
                //
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   458
                // We need to explicitly record them as dropped to
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   459
                // propagate this information when merging two
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   460
                // InternalPathCopies object.
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   461
                let deleted = path_map.tokenize(deleted_path);
46580
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   462
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   463
                let p1_entry = match &mut p1_copies {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   464
                    None => None,
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   465
                    Some(copies) => match copies.entry(deleted) {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   466
                        Entry::Occupied(e) => Some(e),
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   467
                        Entry::Vacant(_) => None,
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   468
                    },
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   469
                };
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   470
                let p2_entry = match &mut p2_copies {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   471
                    None => None,
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   472
                    Some(copies) => match copies.entry(deleted) {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   473
                        Entry::Occupied(e) => Some(e),
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   474
                        Entry::Vacant(_) => None,
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   475
                    },
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   476
                };
46580
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   477
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   478
                match (p1_entry, p2_entry) {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   479
                    (None, None) => (),
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   480
                    (Some(mut e), None) => {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   481
                        e.get_mut().mark_delete(current_rev)
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   482
                    }
46580
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   483
                    (None, Some(mut e)) => {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   484
                        e.get_mut().mark_delete(current_rev)
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   485
                    }
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   486
                    (Some(mut e1), Some(mut e2)) => {
46581
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
   487
                        let cs1 = e1.get_mut();
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
   488
                        let cs2 = e2.get();
46584
aa19d60ac974 copies-rust: use simpler overwrite when value on both side are identical
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46583
diff changeset
   489
                        if cs1 == cs2 {
aa19d60ac974 copies-rust: use simpler overwrite when value on both side are identical
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46583
diff changeset
   490
                            cs1.mark_delete(current_rev);
aa19d60ac974 copies-rust: use simpler overwrite when value on both side are identical
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46583
diff changeset
   491
                        } else {
aa19d60ac974 copies-rust: use simpler overwrite when value on both side are identical
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46583
diff changeset
   492
                            cs1.mark_delete_with_pair(current_rev, &cs2);
aa19d60ac974 copies-rust: use simpler overwrite when value on both side are identical
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46583
diff changeset
   493
                        }
46581
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
   494
                        e2.insert(cs1.clone());
46580
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   495
                    }
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   496
                }
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   497
            }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   498
        }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   499
    }
46579
600f8d510ab6 copies-rust: process copy information of both parent at the same time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46578
diff changeset
   500
    (p1_copies, p2_copies)
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   501
}
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   502
46577
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   503
// insert one new copy information in an InternalPathCopies
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   504
//
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   505
// This deal with chaining and overwrite.
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   506
fn add_one_copy(
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   507
    current_rev: Revision,
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   508
    path_map: &mut TwoWayPathMap,
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   509
    copies: &mut InternalPathCopies,
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   510
    base_copies: &InternalPathCopies,
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   511
    path_dest: &HgPath,
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   512
    path_source: &HgPath,
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   513
) {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   514
    let dest = path_map.tokenize(path_dest);
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   515
    let source = path_map.tokenize(path_source);
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   516
    let entry;
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   517
    if let Some(v) = base_copies.get(&source) {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   518
        entry = match &v.path {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   519
            Some(path) => Some((*(path)).to_owned()),
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   520
            None => Some(source.to_owned()),
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   521
        }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   522
    } else {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   523
        entry = Some(source.to_owned());
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   524
    }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   525
    // Each new entry is introduced by the children, we
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   526
    // record this information as we will need it to take
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   527
    // the right decision when merging conflicting copy
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   528
    // information. See merge_copies_dict for details.
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   529
    match copies.entry(dest) {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   530
        Entry::Vacant(slot) => {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   531
            let ttpc = CopySource::new(current_rev, entry);
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   532
            slot.insert(ttpc);
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   533
        }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   534
        Entry::Occupied(mut slot) => {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   535
            let ttpc = slot.get_mut();
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   536
            ttpc.overwrite(current_rev, entry);
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   537
        }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   538
    }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   539
}
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   540
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   541
/// merge two copies-mapping together, minor and major
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   542
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   543
/// In case of conflict, value from "major" will be picked, unless in some
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   544
/// cases. See inline documentation for details.
46569
34827c95092c copies-rust: remove the ancestor Oracle logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46568
diff changeset
   545
fn merge_copies_dict(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   546
    path_map: &TwoWayPathMap,
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   547
    current_merge: Revision,
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   548
    minor: InternalPathCopies,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   549
    major: InternalPathCopies,
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   550
    get_merge_case: impl Fn(&HgPath) -> MergeCase + Copy,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   551
) -> InternalPathCopies {
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   552
    use crate::utils::{ordmap_union_with_merge, MergeResult};
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   553
46611
1fce35fcb4db copies-rust: pass `PathToken` around by value
Simon Sapin <simon.sapin@octobus.net>
parents: 46587
diff changeset
   554
    ordmap_union_with_merge(minor, major, |&dest, src_minor, src_major| {
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   555
        let (pick, overwrite) = compare_value(
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   556
            current_merge,
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   557
            || get_merge_case(path_map.untokenize(dest)),
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   558
            src_minor,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   559
            src_major,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   560
        );
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   561
        if overwrite {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   562
            let (winner, loser) = match pick {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   563
                MergePick::Major | MergePick::Any => (src_major, src_minor),
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   564
                MergePick::Minor => (src_minor, src_major),
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   565
            };
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   566
            MergeResult::UseNewValue(CopySource::new_from_merge(
46569
34827c95092c copies-rust: remove the ancestor Oracle logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46568
diff changeset
   567
                current_merge,
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   568
                winner,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   569
                loser,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   570
            ))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   571
        } else {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   572
            match pick {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   573
                MergePick::Any | MergePick::Major => {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   574
                    MergeResult::UseRightValue
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   575
                }
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   576
                MergePick::Minor => MergeResult::UseLeftValue,
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   577
            }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   578
        }
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   579
    })
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   580
}
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   581
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   582
/// represent the side that should prevail when merging two
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   583
/// InternalPathCopies
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   584
#[derive(Debug, PartialEq)]
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   585
enum MergePick {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   586
    /// The "major" (p1) side prevails
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   587
    Major,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   588
    /// The "minor" (p2) side prevails
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   589
    Minor,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   590
    /// Any side could be used (because they are the same)
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   591
    Any,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   592
}
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   593
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   594
/// decide which side prevails in case of conflicting values
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   595
#[allow(clippy::if_same_then_else)]
46569
34827c95092c copies-rust: remove the ancestor Oracle logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46568
diff changeset
   596
fn compare_value(
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   597
    current_merge: Revision,
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   598
    merge_case_for_dest: impl Fn() -> MergeCase,
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   599
    src_minor: &CopySource,
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   600
    src_major: &CopySource,
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   601
) -> (MergePick, bool) {
46583
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   602
    if src_major == src_minor {
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   603
        (MergePick::Any, false)
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   604
    } else if src_major.rev == current_merge {
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   605
        // minor is different according to per minor == major check earlier
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   606
        debug_assert!(src_minor.rev != current_merge);
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   607
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   608
        // The last value comes the current merge, this value -will- win
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   609
        // eventually.
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   610
        (MergePick::Major, true)
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   611
    } else if src_minor.rev == current_merge {
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   612
        // The last value comes the current merge, this value -will- win
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   613
        // eventually.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   614
        (MergePick::Minor, true)
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   615
    } else if src_major.path == src_minor.path {
46583
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   616
        debug_assert!(src_major.rev != src_major.rev);
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   617
        // we have the same value, but from other source;
46583
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   618
        if src_major.is_overwritten_by(src_minor) {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   619
            (MergePick::Minor, false)
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
   620
        } else if src_minor.is_overwritten_by(src_major) {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   621
            (MergePick::Major, false)
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   622
        } else {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   623
            (MergePick::Any, true)
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   624
        }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   625
    } else {
46583
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   626
        debug_assert!(src_major.rev != src_major.rev);
46612
80f7567ac9bb copies-rust: pass closures and iterators instead of `&ChangedFiles`
Simon Sapin <simon.sapin@octobus.net>
parents: 46611
diff changeset
   627
        let action = merge_case_for_dest();
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   628
        if src_minor.path.is_some()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   629
            && src_major.path.is_none()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   630
            && action == MergeCase::Salvaged
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   631
        {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   632
            // If the file is "deleted" in the major side but was
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   633
            // salvaged by the merge, we keep the minor side alive
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   634
            (MergePick::Minor, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   635
        } else if src_major.path.is_some()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   636
            && src_minor.path.is_none()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   637
            && action == MergeCase::Salvaged
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   638
        {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   639
            // If the file is "deleted" in the minor side but was
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   640
            // salvaged by the merge, unconditionnaly preserve the
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   641
            // major side.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   642
            (MergePick::Major, true)
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
   643
        } else if src_minor.is_overwritten_by(src_major) {
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   644
            // The information from the minor version are strictly older than
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   645
            // the major version
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   646
            if action == MergeCase::Merged {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   647
                // If the file was actively merged, its means some non-copy
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   648
                // activity happened on the other branch. It
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   649
                // mean the older copy information are still relevant.
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   650
                //
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   651
                // The major side wins such conflict.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   652
                (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   653
            } else {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   654
                // No activity on the minor branch, pick the newer one.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   655
                (MergePick::Major, false)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   656
            }
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
   657
        } else if src_major.is_overwritten_by(src_minor) {
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   658
            if action == MergeCase::Merged {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   659
                // If the file was actively merged, its means some non-copy
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   660
                // activity happened on the other branch. It
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   661
                // mean the older copy information are still relevant.
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   662
                //
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   663
                // The major side wins such conflict.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   664
                (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   665
            } else {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   666
                // No activity on the minor branch, pick the newer one.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   667
                (MergePick::Minor, false)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   668
            }
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   669
        } else if src_minor.path.is_none() {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   670
            // the minor side has no relevant information, pick the alive one
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   671
            (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   672
        } else if src_major.path.is_none() {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   673
            // the major side has no relevant information, pick the alive one
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   674
            (MergePick::Minor, true)
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   675
        } else {
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   676
            // by default the major side wins
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   677
            (MergePick::Major, true)
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   678
        }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   679
    }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   680
}