rust/hg-core/src/copy_tracing.rs
author Simon Sapin <simon.sapin@octobus.net>
Tue, 27 Apr 2021 14:20:48 +0200
changeset 47117 60d852ae7e7b
parent 46658 fa21633af201
child 49916 321e2b7bc95c
permissions -rw-r--r--
dirstate-tree: Paralellize the status algorithm with Rayon The `rayon` crate exposes "parallel iterators" that work like normal iterators but dispatch work on different items to an implicit global thread pool. Differential Revision: https://phab.mercurial-scm.org/D10551
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
}