rust/hg-core/src/copy_tracing.rs
author Simon Sapin <simon.sapin@octobus.net>
Wed, 23 Dec 2020 11:48:16 +0100
changeset 46586 435d9fc72646
parent 46585 60b2b7ecf9cb
child 46587 cb4b0b0c6de4
permissions -rw-r--r--
copies-rust: extract generic map merge logic from merge_copies_dict This deduplicates the copy-tracing-specific logic Differential Revision: https://phab.mercurial-scm.org/D9682
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
     1
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
     2
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
     3
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
     4
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
     5
46153
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
     6
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
     7
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
     8
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
     9
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    10
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
    11
use std::collections::HashMap;
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    12
use std::convert::TryInto;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    13
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    14
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
    15
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
    16
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
    17
46582
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
    18
#[derive(Clone, Debug)]
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
    19
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
    20
    /// 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
    21
    rev: Revision,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    22
    /// 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
    23
    /// 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
    24
    path: Option<PathToken>,
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    25
    /// 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
    26
    /// 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
    27
    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
    28
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    29
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    30
impl CopySource {
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    31
    /// 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
    32
    ///
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    33
    /// 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
    34
    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
    35
        Self {
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    36
            rev,
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    37
            path,
46585
60b2b7ecf9cb copies-rust: use imrs::OrdSet instead of imrs::HashSet
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46584
diff changeset
    38
            overwritten: OrdSet::new(),
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    39
        }
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    40
    }
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    41
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    42
    /// 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
    43
    ///
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    44
    /// 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
    45
    /// some entries.
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    46
    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
    47
        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
    48
        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
    49
        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
    50
        overwritten.insert(winner.rev);
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    51
        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
    52
        Self {
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    53
            rev,
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    54
            path: winner.path,
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    55
            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
    56
        }
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    57
    }
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    58
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    59
    /// 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
    60
    ///
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    61
    /// 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
    62
    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
    63
        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
    64
        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
    65
        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
    66
    }
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
    /// 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
    69
    ///
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    70
    /// 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
    71
    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
    72
        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
    73
        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
    74
        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
    75
    }
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    76
46581
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    77
    /// 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
    78
    ///
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    79
    /// 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
    80
    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
    81
        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
    82
        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
    83
            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
    84
        }
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    85
        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
    86
        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
    87
        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
    88
    }
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
    89
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
    90
    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
    91
        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
    92
    }
46567
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    93
}
b6f65d90e8af copies-rust: add methods to build and update CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46566
diff changeset
    94
46582
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
    95
// 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
    96
// the same.
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
    97
impl PartialEq for CopySource {
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
    98
    fn eq(&self, other: &Self) -> bool {
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
    99
        #[cfg(debug_assertions)]
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   100
        {
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   101
            if self.rev == other.rev {
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   102
                debug_assert!(self.path == other.path);
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   103
                debug_assert!(self.overwritten == other.overwritten);
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   104
            }
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   105
        }
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   106
        self.rev == other.rev
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
}
b0a3ca02d17a copies-rust: implement PartialEqual manually
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46581
diff changeset
   109
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   110
/// 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
   111
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
   112
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   113
/// hold parent 1, parent 2 and relevant files actions.
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   114
pub type RevInfo<'a> = (Revision, Revision, ChangedFiles<'a>);
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   115
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   116
/// represent the files affected by a changesets
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   117
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   118
/// This hold a subset of mercurial.metadata.ChangingFiles as we do not need
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   119
/// all the data categories tracked by it.
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   120
/// This hold a subset of mercurial.metadata.ChangingFiles as we do not need
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   121
/// all the data categories tracked by it.
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   122
pub struct ChangedFiles<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   123
    nb_items: u32,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   124
    index: &'a [u8],
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   125
    data: &'a [u8],
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   126
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   127
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
   128
/// 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
   129
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
   130
    /// 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
   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
    /// (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
   133
    /// 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
   134
    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
   135
    /// 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
   136
    /// 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
   137
    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
   138
    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
   139
}
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   140
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   141
/// 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
   142
///
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   143
/// 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
   144
#[derive(PartialEq)]
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   145
enum MergeCase {
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   146
    /// 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
   147
    Merged,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   148
    /// 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
   149
    Salvaged,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   150
    /// 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
   151
    Normal,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   152
}
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   153
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   154
type FileChange<'a> = (u8, &'a HgPath, &'a HgPath);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   155
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   156
const EMPTY: &[u8] = b"";
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   157
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
   158
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
   159
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
   160
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
   161
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
   162
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
   163
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
   164
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   165
impl<'a> ChangedFiles<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   166
    const INDEX_START: usize = 4;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   167
    const ENTRY_SIZE: u32 = 9;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   168
    const FILENAME_START: u32 = 1;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   169
    const COPY_SOURCE_START: u32 = 5;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   170
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   171
    pub fn new(data: &'a [u8]) -> Self {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   172
        assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   173
            data.len() >= 4,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   174
            "data size ({}) is too small to contain the header (4)",
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   175
            data.len()
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   176
        );
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   177
        let nb_items_raw: [u8; 4] = (&data[0..=3])
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   178
            .try_into()
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   179
            .expect("failed to turn 4 bytes into 4 bytes");
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   180
        let nb_items = u32::from_be_bytes(nb_items_raw);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   181
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   182
        let index_size = (nb_items * Self::ENTRY_SIZE) as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   183
        let index_end = Self::INDEX_START + index_size;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   184
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   185
        assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   186
            data.len() >= index_end,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   187
            "data size ({}) is too small to fit the index_data ({})",
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   188
            data.len(),
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   189
            index_end
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   190
        );
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   191
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   192
        let ret = ChangedFiles {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   193
            nb_items,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   194
            index: &data[Self::INDEX_START..index_end],
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   195
            data: &data[index_end..],
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   196
        };
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   197
        let max_data = ret.filename_end(nb_items - 1) as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   198
        assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   199
            ret.data.len() >= max_data,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   200
            "data size ({}) is too small to fit all data ({})",
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   201
            data.len(),
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   202
            index_end + max_data
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   203
        );
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   204
        ret
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   205
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   206
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   207
    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
   208
        ChangedFiles {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   209
            nb_items: 0,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   210
            index: EMPTY,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   211
            data: EMPTY,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   212
        }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   213
    }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   214
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   215
    /// internal function to return an individual entry at a given index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   216
    fn entry(&'a self, idx: u32) -> FileChange<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   217
        if idx >= self.nb_items {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   218
            panic!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   219
                "index for entry is higher that the number of file {} >= {}",
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   220
                idx, self.nb_items
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   221
            )
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   222
        }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   223
        let flags = self.flags(idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   224
        let filename = self.filename(idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   225
        let copy_idx = self.copy_idx(idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   226
        let copy_source = self.filename(copy_idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   227
        (flags, filename, copy_source)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   228
    }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   229
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   230
    /// internal function to return the filename of the entry at a given index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   231
    fn filename(&self, idx: u32) -> &HgPath {
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 filename_start;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   233
        if idx == 0 {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   234
            filename_start = 0;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   235
        } else {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   236
            filename_start = self.filename_end(idx - 1)
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   237
        }
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
        let filename_end = self.filename_end(idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   239
        let filename_start = filename_start as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   240
        let filename_end = filename_end as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   241
        HgPath::new(&self.data[filename_start..filename_end])
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   242
    }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   243
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   244
    /// internal function to return the flag field of the entry at a given
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   245
    /// index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   246
    fn flags(&self, idx: u32) -> u8 {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   247
        let idx = idx as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   248
        self.index[idx * (Self::ENTRY_SIZE as usize)]
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   249
    }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   250
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   251
    /// internal function to return the end of a filename part at a given index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   252
    fn filename_end(&self, idx: u32) -> u32 {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   253
        let start = (idx * Self::ENTRY_SIZE) + Self::FILENAME_START;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   254
        let end = (idx * Self::ENTRY_SIZE) + Self::COPY_SOURCE_START;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   255
        let start = start as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   256
        let end = end as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   257
        let raw = (&self.index[start..end])
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   258
            .try_into()
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   259
            .expect("failed to turn 4 bytes into 4 bytes");
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   260
        u32::from_be_bytes(raw)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   261
    }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   262
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   263
    /// internal function to return index of the copy source of the entry at a
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   264
    /// given index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   265
    fn copy_idx(&self, idx: u32) -> u32 {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   266
        let start = (idx * Self::ENTRY_SIZE) + Self::COPY_SOURCE_START;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   267
        let end = (idx + 1) * Self::ENTRY_SIZE;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   268
        let start = start as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   269
        let end = end as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   270
        let raw = (&self.index[start..end])
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   271
            .try_into()
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   272
            .expect("failed to turn 4 bytes into 4 bytes");
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   273
        u32::from_be_bytes(raw)
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   274
    }
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
   275
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
   276
    /// Return an iterator over all the `Action` in this instance.
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
   277
    fn iter_actions(&self) -> ActionsIterator {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   278
        ActionsIterator {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   279
            changes: &self,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   280
            current: 0,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   281
        }
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
   282
    }
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   283
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   284
    /// 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
   285
    fn get_merge_case(&self, path: &HgPath) -> MergeCase {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   286
        if self.nb_items == 0 {
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   287
            return MergeCase::Normal;
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   288
        }
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   289
        let mut low_part = 0;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   290
        let mut high_part = self.nb_items;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   291
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   292
        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
   293
            let cursor = (low_part + high_part - 1) / 2;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   294
            let (flags, filename, _source) = self.entry(cursor);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   295
            match path.cmp(filename) {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   296
                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
   297
                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
   298
                Ordering::Equal => {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   299
                    return match flags & ACTION_MASK {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   300
                        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
   301
                        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
   302
                        _ => 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
   303
                    };
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   304
                }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   305
            }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   306
        }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   307
        MergeCase::Normal
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   308
    }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   309
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   310
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   311
struct ActionsIterator<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   312
    changes: &'a ChangedFiles<'a>,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   313
    current: u32,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   314
}
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   315
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   316
impl<'a> Iterator for ActionsIterator<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   317
    type Item = Action<'a>;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   318
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   319
    fn next(&mut self) -> Option<Action<'a>> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   320
        while self.current < self.changes.nb_items {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   321
            let (flags, file, source) = self.changes.entry(self.current);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   322
            self.current += 1;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   323
            if (flags & ACTION_MASK) == REMOVED {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   324
                return Some(Action::Removed(file));
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   325
            }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   326
            let copy = flags & COPY_MASK;
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
   327
            if copy == P1_COPY {
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   328
                return Some(Action::CopiedFromP1(file, 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
   329
            } else if copy == P2_COPY {
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   330
                return Some(Action::CopiedFromP2(file, source));
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   331
            }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   332
        }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   333
        return None;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   334
    }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   335
}
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   336
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   337
/// A small struct whose purpose is to ensure lifetime of bytes referenced in
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   338
/// ChangedFiles
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   339
///
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   340
/// It is passed to the RevInfoMaker callback who can assign any necessary
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   341
/// content to the `data` attribute. The copy tracing code is responsible for
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   342
/// keeping the DataHolder alive at least as long as the ChangedFiles object.
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   343
pub struct DataHolder<D> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   344
    /// RevInfoMaker callback should assign data referenced by the
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   345
    /// ChangedFiles struct it return to this attribute. The DataHolder
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   346
    /// lifetime will be at least as long as the ChangedFiles one.
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   347
    pub data: Option<D>,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   348
}
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   349
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   350
pub type RevInfoMaker<'a, D> =
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   351
    Box<dyn for<'r> Fn(Revision, &'r mut DataHolder<D>) -> RevInfo<'r> + 'a>;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   352
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   353
/// 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
   354
/// PathToken
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   355
///
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   356
/// 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
   357
/// 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
   358
#[derive(Clone, Debug, Default)]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   359
struct TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   360
    token: HashMap<HgPathBuf, PathToken>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   361
    path: Vec<HgPathBuf>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   362
}
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   363
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   364
impl TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   365
    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
   366
        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
   367
            Some(a) => *a,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   368
            None => {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   369
                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
   370
                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
   371
                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
   372
                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
   373
                a
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   374
            }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   375
        }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   376
    }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   377
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   378
    fn untokenize(&self, token: PathToken) -> &HgPathBuf {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   379
        assert!(token < self.path.len(), format!("Unknown token: {}", token));
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   380
        &self.path[token]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   381
    }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   382
}
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   383
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   384
/// Same as mercurial.copies._combine_changeset_copies, but in Rust.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   385
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   386
/// Arguments are:
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   387
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   388
/// revs: all revisions to be considered
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   389
/// children: a {parent ? [childrens]} mapping
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   390
/// target_rev: the final revision we are combining copies to
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   391
/// rev_info(rev): callback to get revision information:
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   392
///   * first parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   393
///   * second parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   394
///   * ChangedFiles
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   395
/// isancestors(low_rev, high_rev): callback to check if a revision is an
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   396
///                                 ancestor of another
46569
34827c95092c copies-rust: remove the ancestor Oracle logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46568
diff changeset
   397
pub fn combine_changeset_copies<D>(
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   398
    revs: Vec<Revision>,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   399
    mut children_count: HashMap<Revision, usize>,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   400
    target_rev: Revision,
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   401
    rev_info: RevInfoMaker<D>,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   402
) -> PathCopies {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   403
    let mut all_copies = HashMap::new();
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   404
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   405
    let mut path_map = TwoWayPathMap::default();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   406
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   407
    for rev in revs {
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   408
        let mut d: DataHolder<D> = DataHolder { data: None };
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   409
        let (p1, p2, changes) = rev_info(rev, &mut d);
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   410
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   411
        // We will chain the copies information accumulated for the parent with
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   412
        // the individual copies information the curent revision.  Creating a
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   413
        // new TimeStampedPath for each `rev` → `children` vertex.
46575
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   414
        // 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
   415
        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
   416
            NULL_REVISION => None,
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   417
            _ => get_and_clean_parent_copies(
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   418
                &mut all_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   419
                &mut children_count,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   420
                p1,
46575
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   421
            ), // 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
   422
        };
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   423
        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
   424
            NULL_REVISION => None,
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   425
            _ => get_and_clean_parent_copies(
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   426
                &mut all_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   427
                &mut children_count,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   428
                p2,
46575
389b0328b789 copies-rust: get the parents' copies earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46569
diff changeset
   429
            ), // 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
   430
        };
46576
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   431
        // combine it with data for that 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
   432
        let (p1_copies, 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
   433
            chain_changes(&mut path_map, p1_copies, p2_copies, &changes, rev);
46576
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   434
        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
   435
            (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
   436
            (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
   437
            (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
   438
            (Some(p1_copies), Some(p2_copies)) => Some(merge_copies_dict(
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   439
                &path_map, rev, p2_copies, p1_copies, &changes,
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   440
            )),
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   441
        };
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   442
        if let Some(c) = copies {
f8bdc8329d77 copies-rust: use matching to select the final copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46575
diff changeset
   443
            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
   444
        }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   445
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   446
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   447
    // Drop internal information (like the timestamp) and return the final
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   448
    // mapping.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   449
    let tt_result = all_copies
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   450
        .remove(&target_rev)
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   451
        .expect("target revision was not processed");
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   452
    let mut result = PathCopies::default();
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   453
    for (dest, tt_source) in tt_result {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   454
        if let Some(path) = tt_source.path {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   455
            let path_dest = path_map.untokenize(dest).to_owned();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   456
            let path_path = path_map.untokenize(path).to_owned();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   457
            result.insert(path_dest, path_path);
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   458
        }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   459
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   460
    result
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   461
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   462
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   463
/// 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
   464
///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   465
/// 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
   466
/// the cache.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   467
///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   468
/// 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
   469
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
   470
    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
   471
    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
   472
    parent_rev: Revision,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   473
) -> Option<InternalPathCopies> {
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   474
    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
   475
    *count -= 1;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   476
    if *count == 0 {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   477
        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
   478
            Some(c) => Some(c),
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   479
            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
   480
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   481
    } else {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   482
        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
   483
            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
   484
            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
   485
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   486
    }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   487
}
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   488
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
   489
/// 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
   490
/// the result
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
   491
fn chain_changes(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   492
    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
   493
    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
   494
    base_p2_copies: Option<InternalPathCopies>,
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
   495
    changes: &ChangedFiles,
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
   496
    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
   497
) -> (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
   498
    // 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
   499
    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
   500
        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
   501
    }
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
   502
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
   503
    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
   504
    let mut p2_copies = base_p2_copies.clone();
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
   505
    for action in changes.iter_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
   506
        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
   507
            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
   508
                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
   509
                    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
   510
                    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
   511
                        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
   512
                        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
   513
                        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
   514
                        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
   515
                        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
   516
                        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
   517
                    ),
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
   518
                }
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
   519
            }
a34cd9aa3323 copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46577
diff changeset
   520
            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
   521
                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
   522
                    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
   523
                    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
   524
                        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
   525
                        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
   526
                        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
   527
                        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
   528
                        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
   529
                        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
   530
                    ),
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
   531
                }
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
   532
            }
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   533
            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
   534
                // 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
   535
                //
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
   536
                // 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
   537
                // 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
   538
                // InternalPathCopies object.
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   539
                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
   540
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   541
                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
   542
                    None => None,
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   543
                    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
   544
                        Entry::Occupied(e) => Some(e),
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   545
                        Entry::Vacant(_) => None,
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   546
                    },
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   547
                };
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   548
                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
   549
                    None => None,
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   550
                    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
   551
                        Entry::Occupied(e) => Some(e),
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   552
                        Entry::Vacant(_) => None,
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   553
                    },
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
   554
                };
46580
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   555
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   556
                match (p1_entry, p2_entry) {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   557
                    (None, None) => (),
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   558
                    (Some(mut e), None) => {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   559
                        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
   560
                    }
46580
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   561
                    (None, Some(mut e)) => {
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   562
                        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
   563
                    }
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   564
                    (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
   565
                        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
   566
                        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
   567
                        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
   568
                            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
   569
                        } 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
   570
                            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
   571
                        }
46581
d6d57bfc1a1b copies-rust: record "overwritten" information from both side on delete
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46580
diff changeset
   572
                        e2.insert(cs1.clone());
46580
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   573
                    }
2076df13d00f copies-rust: refactor the "deletion" case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46579
diff changeset
   574
                }
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
   575
            }
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
   576
        }
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
   577
    }
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
   578
    (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
   579
}
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
   580
46577
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   581
// 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
   582
//
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   583
// 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
   584
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
   585
    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
   586
    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
   587
    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
   588
    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
   589
    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
   590
    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
   591
) {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   592
    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
   593
    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
   594
    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
   595
    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
   596
        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
   597
            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
   598
            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
   599
        }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   600
    } else {
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   601
        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
   602
    }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   603
    // 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
   604
    // 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
   605
    // 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
   606
    // 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
   607
    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
   608
        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
   609
            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
   610
            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
   611
        }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   612
        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
   613
            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
   614
            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
   615
        }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   616
    }
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   617
}
d2ad44b8ef6a copies-rust: extract the processing of a single copy information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46576
diff changeset
   618
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   619
/// 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
   620
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   621
/// 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
   622
/// 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
   623
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
   624
    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
   625
    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
   626
    minor: InternalPathCopies,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   627
    major: InternalPathCopies,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   628
    changes: &ChangedFiles,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   629
) -> InternalPathCopies {
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   630
    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
   631
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   632
    ordmap_union_with_merge(minor, major, |dest, 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
   633
        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
   634
            path_map,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   635
            current_merge,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   636
            changes,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   637
            dest,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   638
            src_minor,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   639
            src_major,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   640
        );
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   641
        if overwrite {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   642
            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
   643
                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
   644
                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
   645
            };
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   646
            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
   647
                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
   648
                winner,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   649
                loser,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   650
            ))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   651
        } else {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   652
            match pick {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   653
                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
   654
                    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
   655
                }
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   656
                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
   657
            }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   658
        }
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46585
diff changeset
   659
    })
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   660
}
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   661
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   662
/// 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
   663
/// InternalPathCopies
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   664
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
   665
    /// 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
   666
    Major,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   667
    /// 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
   668
    Minor,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   669
    /// 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
   670
    Any,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   671
}
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   672
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   673
/// 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
   674
#[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
   675
fn compare_value(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   676
    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
   677
    current_merge: Revision,
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
    changes: &ChangedFiles,
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
   679
    dest: &PathToken,
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   680
    src_minor: &CopySource,
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   681
    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
   682
) -> (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
   683
    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
   684
        (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
   685
    } 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
   686
        // 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
   687
        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
   688
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   689
        // 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
   690
        // eventually.
8fcf07e6bbb4 copies-rust: make more use of the new comparison property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46582
diff changeset
   691
        (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
   692
    } 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
   693
        // 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
   694
        // 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
   695
        (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
   696
    } 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
   697
        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
   698
        // 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
   699
        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
   700
            (MergePick::Minor, false)
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
   701
        } 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
   702
            (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
   703
        } 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
   704
            (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
   705
        }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   706
    } 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
   707
        debug_assert!(src_major.rev != src_major.rev);
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   708
        let dest_path = path_map.untokenize(*dest);
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   709
        let action = changes.get_merge_case(dest_path);
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   710
        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
   711
            && src_major.path.is_none()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   712
            && action == MergeCase::Salvaged
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   713
        {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   714
            // 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
   715
            // 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
   716
            (MergePick::Minor, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   717
        } 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
   718
            && src_minor.path.is_none()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   719
            && action == MergeCase::Salvaged
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   720
        {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   721
            // 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
   722
            // 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
   723
            // 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
   724
            (MergePick::Major, true)
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
   725
        } 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
   726
            // 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
   727
            // the major version
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   728
            if action == MergeCase::Merged {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   729
                // 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
   730
                // 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
   731
                // 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
   732
                //
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   733
                // 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
   734
                (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   735
            } else {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   736
                // 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
   737
                (MergePick::Major, false)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   738
            }
46568
0d840b9d200d copies-rust: track "overwrites" directly within CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46567
diff changeset
   739
        } 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
   740
            if action == MergeCase::Merged {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   741
                // 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
   742
                // 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
   743
                // 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
   744
                //
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   745
                // 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
   746
                (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   747
            } else {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   748
                // 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
   749
                (MergePick::Minor, false)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   750
            }
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   751
        } 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
   752
            // 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
   753
            (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   754
        } 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
   755
            // 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
   756
            (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
   757
        } else {
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   758
            // 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
   759
            (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
   760
        }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   761
    }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   762
}