rust/hg-core/src/sparse.rs
author Arseniy Alekseyev <aalekseyev@janestreet.com>
Wed, 05 Oct 2022 15:45:05 -0400
changeset 49517 52464a20add0
parent 49488 7c93e38a0bbd
child 49930 e98fd81bb151
permissions -rw-r--r--
rhg: parallellize computation of [unsure_is_modified] [unsure_is_modified] is called for every file for which we can't determine its status based on its size and mtime alone. In particular, this happens if the mtime of the file changes without its contents changing. Parallellizing this improves performance significantly when we have many of these files. Here's an example run (on a repo with ~400k files after dropping FS caches) ``` before: real 0m53.901s user 0m27.806s sys 0m31.325s after: real 0m32.017s user 0m34.277s sys 1m26.250s ``` Another example run (a different FS): ``` before: real 3m28.479s user 0m31.800s sys 0m25.324s after: real 0m29.751s user 0m41.814s sys 1m15.387s ```
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     1
use std::{collections::HashSet, path::Path};
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     2
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     3
use format_bytes::{write_bytes, DisplayBytes};
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     4
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     5
use crate::{
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     6
    errors::HgError,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     7
    filepatterns::parse_pattern_file_contents,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     8
    matchers::{
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     9
        AlwaysMatcher, DifferenceMatcher, IncludeMatcher, Matcher,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    10
        UnionMatcher,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    11
    },
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    12
    operations::cat,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    13
    repo::Repo,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    14
    requirements::SPARSE_REQUIREMENT,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    15
    utils::{hg_path::HgPath, SliceExt},
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    16
    IgnorePattern, PatternError, PatternFileWarning, PatternSyntax, Revision,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    17
    NULL_REVISION,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    18
};
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    19
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    20
/// Command which is triggering the config read
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    21
#[derive(Copy, Clone, Debug)]
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    22
pub enum SparseConfigContext {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    23
    Sparse,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    24
    Narrow,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    25
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    26
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    27
impl DisplayBytes for SparseConfigContext {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    28
    fn display_bytes(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
        &self,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    30
        output: &mut dyn std::io::Write,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    31
    ) -> std::io::Result<()> {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    32
        match self {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    33
            SparseConfigContext::Sparse => write_bytes!(output, b"sparse"),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    34
            SparseConfigContext::Narrow => write_bytes!(output, b"narrow"),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    35
        }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    36
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    38
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    39
/// Possible warnings when reading sparse configuration
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    40
#[derive(Debug, derive_more::From)]
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    41
pub enum SparseWarning {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    42
    /// Warns about improper paths that start with "/"
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    43
    RootWarning {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    44
        context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    45
        line: Vec<u8>,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    46
    },
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    47
    /// Warns about a profile missing from the given changelog revision
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
    ProfileNotFound { profile: Vec<u8>, rev: Revision },
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    49
    #[from]
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    50
    Pattern(PatternFileWarning),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    51
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    52
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    53
/// Parsed sparse config
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    54
#[derive(Debug, Default)]
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    55
pub struct SparseConfig {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    56
    // Line-separated
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    57
    pub(crate) includes: Vec<u8>,
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    58
    // Line-separated
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    59
    pub(crate) excludes: Vec<u8>,
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    60
    pub(crate) profiles: HashSet<Vec<u8>>,
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    61
    pub(crate) warnings: Vec<SparseWarning>,
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    62
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    63
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    64
/// All possible errors when reading sparse/narrow config
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    65
#[derive(Debug, derive_more::From)]
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    66
pub enum SparseConfigError {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    67
    IncludesAfterExcludes {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    68
        context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    69
    },
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    70
    EntryOutsideSection {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    71
        context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    72
        line: Vec<u8>,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    73
    },
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    74
    /// Narrow config does not support '%include' directives
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    75
    IncludesInNarrow,
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    76
    /// An invalid pattern prefix was given to the narrow spec. Includes the
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    77
    /// entire pattern for context.
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    78
    InvalidNarrowPrefix(Vec<u8>),
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    79
    #[from]
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    80
    HgError(HgError),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    81
    #[from]
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    82
    PatternError(PatternError),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    83
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    84
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    85
/// Parse sparse config file content.
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    86
pub(crate) fn parse_config(
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    87
    raw: &[u8],
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    88
    context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    89
) -> Result<SparseConfig, SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    90
    let mut includes = vec![];
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    91
    let mut excludes = vec![];
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    92
    let mut profiles = HashSet::new();
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    93
    let mut warnings = vec![];
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    94
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    95
    #[derive(PartialEq, Eq)]
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    96
    enum Current {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    97
        Includes,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    98
        Excludes,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    99
        None,
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49488
diff changeset
   100
    }
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   101
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   102
    let mut current = Current::None;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   103
    let mut in_section = false;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   104
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   105
    for line in raw.split(|c| *c == b'\n') {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   106
        let line = line.trim();
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   107
        if line.is_empty() || line[0] == b'#' {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   108
            // empty or comment line, skip
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   109
            continue;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   110
        }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   111
        if line.starts_with(b"%include ") {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   112
            let profile = line[b"%include ".len()..].trim();
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   113
            if !profile.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   114
                profiles.insert(profile.into());
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   115
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   116
        } else if line == b"[include]" {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   117
            if in_section && current == Current::Includes {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   118
                return Err(SparseConfigError::IncludesAfterExcludes {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   119
                    context,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   120
                });
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   121
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   122
            in_section = true;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   123
            current = Current::Includes;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   124
            continue;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   125
        } else if line == b"[exclude]" {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   126
            in_section = true;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   127
            current = Current::Excludes;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   128
        } else {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   129
            if current == Current::None {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   130
                return Err(SparseConfigError::EntryOutsideSection {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   131
                    context,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   132
                    line: line.into(),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   133
                });
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   134
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   135
            if line.trim().starts_with(b"/") {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   136
                warnings.push(SparseWarning::RootWarning {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   137
                    context,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   138
                    line: line.into(),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   139
                });
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   140
                continue;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   141
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   142
            match current {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   143
                Current::Includes => {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   144
                    includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   145
                    includes.extend(line.iter());
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   146
                }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   147
                Current::Excludes => {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   148
                    excludes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   149
                    excludes.extend(line.iter());
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   150
                }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   151
                Current::None => unreachable!(),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   152
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   153
        }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   154
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   155
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   156
    Ok(SparseConfig {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   157
        includes,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   158
        excludes,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   159
        profiles,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   160
        warnings,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   161
    })
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   162
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   163
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   164
fn read_temporary_includes(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   165
    repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   166
) -> Result<Vec<Vec<u8>>, SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   167
    let raw = repo.hg_vfs().try_read("tempsparse")?.unwrap_or(vec![]);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   168
    if raw.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   169
        return Ok(vec![]);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   170
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   171
    Ok(raw.split(|c| *c == b'\n').map(ToOwned::to_owned).collect())
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   172
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   173
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   174
/// Obtain sparse checkout patterns for the given revision
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   175
fn patterns_for_rev(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   176
    repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   177
    rev: Revision,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   178
) -> Result<Option<SparseConfig>, SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   179
    if !repo.has_sparse() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   180
        return Ok(None);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   181
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   182
    let raw = repo.hg_vfs().try_read("sparse")?.unwrap_or(vec![]);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   183
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   184
    if raw.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   185
        return Ok(None);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   186
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   187
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   188
    let mut config = parse_config(&raw, SparseConfigContext::Sparse)?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   189
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   190
    if !config.profiles.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   191
        let mut profiles: Vec<Vec<u8>> = config.profiles.into_iter().collect();
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   192
        let mut visited = HashSet::new();
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   193
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   194
        while let Some(profile) = profiles.pop() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   195
            if visited.contains(&profile) {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   196
                continue;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   197
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   198
            visited.insert(profile.to_owned());
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   199
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   200
            let output =
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   201
                cat(repo, &rev.to_string(), vec![HgPath::new(&profile)])
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   202
                    .map_err(|_| {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   203
                        HgError::corrupted(format!(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   204
                            "dirstate points to non-existent parent node"
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   205
                        ))
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   206
                    })?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   207
            if output.results.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   208
                config.warnings.push(SparseWarning::ProfileNotFound {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   209
                    profile: profile.to_owned(),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   210
                    rev,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   211
                })
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   212
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   213
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   214
            let subconfig = parse_config(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   215
                &output.results[0].1,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   216
                SparseConfigContext::Sparse,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   217
            )?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   218
            if !subconfig.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   219
                config.includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   220
                config.includes.extend(&subconfig.includes);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   221
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   222
            if !subconfig.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   223
                config.includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   224
                config.excludes.extend(&subconfig.excludes);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   225
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   226
            config.warnings.extend(subconfig.warnings.into_iter());
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   227
            profiles.extend(subconfig.profiles.into_iter());
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   228
        }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   229
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   230
        config.profiles = visited;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   231
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   232
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   233
    if !config.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   234
        config.includes.extend(b"\n.hg*");
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   235
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   236
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   237
    Ok(Some(config))
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   238
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   239
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   240
/// Obtain a matcher for sparse working directories.
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   241
pub fn matcher(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   242
    repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   243
) -> Result<(Box<dyn Matcher + Sync>, Vec<SparseWarning>), SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   244
    let mut warnings = vec![];
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   245
    if !repo.requirements().contains(SPARSE_REQUIREMENT) {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   246
        return Ok((Box::new(AlwaysMatcher), warnings));
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   247
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   248
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   249
    let parents = repo.dirstate_parents()?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   250
    let mut revs = vec![];
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   251
    let p1_rev =
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   252
        repo.changelog()?
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   253
            .rev_from_node(parents.p1.into())
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   254
            .map_err(|_| {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   255
                HgError::corrupted(format!(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   256
                    "dirstate points to non-existent parent node"
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   257
                ))
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   258
            })?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   259
    if p1_rev != NULL_REVISION {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   260
        revs.push(p1_rev)
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   261
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   262
    let p2_rev =
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   263
        repo.changelog()?
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   264
            .rev_from_node(parents.p2.into())
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   265
            .map_err(|_| {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   266
                HgError::corrupted(format!(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   267
                    "dirstate points to non-existent parent node"
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   268
                ))
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   269
            })?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   270
    if p2_rev != NULL_REVISION {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   271
        revs.push(p2_rev)
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   272
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   273
    let mut matchers = vec![];
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   274
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   275
    for rev in revs.iter() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   276
        let config = patterns_for_rev(repo, *rev);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   277
        if let Ok(Some(config)) = config {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   278
            warnings.extend(config.warnings);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   279
            let mut m: Box<dyn Matcher + Sync> = Box::new(AlwaysMatcher);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   280
            if !config.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   281
                let (patterns, subwarnings) = parse_pattern_file_contents(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   282
                    &config.includes,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   283
                    Path::new(""),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   284
                    Some(b"relglob:".as_ref()),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   285
                    false,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   286
                )?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   287
                warnings.extend(subwarnings.into_iter().map(From::from));
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   288
                m = Box::new(IncludeMatcher::new(patterns)?);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   289
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   290
            if !config.excludes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   291
                let (patterns, subwarnings) = parse_pattern_file_contents(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   292
                    &config.excludes,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   293
                    Path::new(""),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   294
                    Some(b"relglob:".as_ref()),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   295
                    false,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   296
                )?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   297
                warnings.extend(subwarnings.into_iter().map(From::from));
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   298
                m = Box::new(DifferenceMatcher::new(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   299
                    m,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   300
                    Box::new(IncludeMatcher::new(patterns)?),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   301
                ));
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   302
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   303
            matchers.push(m);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   304
        }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   305
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   306
    let result: Box<dyn Matcher + Sync> = match matchers.len() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   307
        0 => Box::new(AlwaysMatcher),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   308
        1 => matchers.pop().expect("1 is equal to 0"),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   309
        _ => Box::new(UnionMatcher::new(matchers)),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   310
    };
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   311
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   312
    let matcher =
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   313
        force_include_matcher(result, &read_temporary_includes(repo)?)?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   314
    Ok((matcher, warnings))
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   315
}
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   316
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   317
/// Returns a matcher that returns true for any of the forced includes before
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   318
/// testing against the actual matcher
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   319
fn force_include_matcher(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   320
    result: Box<dyn Matcher + Sync>,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   321
    temp_includes: &[Vec<u8>],
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   322
) -> Result<Box<dyn Matcher + Sync>, PatternError> {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   323
    if temp_includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   324
        return Ok(result);
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   325
    }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   326
    let forced_include_matcher = IncludeMatcher::new(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   327
        temp_includes
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   328
            .into_iter()
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   329
            .map(|include| {
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   330
                IgnorePattern::new(PatternSyntax::Path, include, Path::new(""))
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   331
            })
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   332
            .collect(),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   333
    )?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   334
    Ok(Box::new(UnionMatcher::new(vec![
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   335
        Box::new(forced_include_matcher),
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   336
        result,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   337
    ])))
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   338
}