rust/hg-core/src/repo.rs
author Simon Sapin <simon.sapin@octobus.net>
Thu, 04 Feb 2021 14:29:47 +0100
changeset 46485 f031fe1c6ede
parent 46484 a6e4e4650bac
child 46486 d7685105e504
permissions -rw-r--r--
rhg: Abort based on config on share-safe mismatch Differential Revision: https://phab.mercurial-scm.org/D9963
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46484
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46463
diff changeset
     1
use crate::config::Config;
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46442
diff changeset
     2
use crate::errors::{HgError, IoResultExt};
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     3
use crate::requirements;
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
     4
use crate::utils::files::get_path_from_bytes;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     5
use memmap::{Mmap, MmapOptions};
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
     6
use std::collections::HashSet;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     7
use std::path::{Path, PathBuf};
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     8
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     9
/// A repository on disk
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    10
pub struct Repo {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    11
    working_directory: PathBuf,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    12
    dot_hg: PathBuf,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    13
    store: PathBuf,
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    14
    requirements: HashSet<String>,
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    15
}
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    16
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    17
#[derive(Debug, derive_more::From)]
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    18
pub enum RepoFindError {
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    19
    NotFoundInCurrentDirectoryOrAncestors {
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    20
        current_directory: PathBuf,
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    21
    },
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    22
    #[from]
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    23
    Other(HgError),
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    24
}
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    25
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    26
/// Filesystem access abstraction for the contents of a given "base" diretory
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    27
#[derive(Clone, Copy)]
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    28
pub(crate) struct Vfs<'a> {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    29
    base: &'a Path,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    30
}
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    31
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    32
impl Repo {
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    33
    /// Search the current directory and its ancestores for a repository:
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    34
    /// a working directory that contains a `.hg` sub-directory.
46485
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    35
    pub fn find(config: &Config) -> Result<Self, RepoFindError> {
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    36
        let current_directory = crate::utils::current_dir()?;
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    37
        // ancestors() is inclusive: it first yields `current_directory` as-is.
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    38
        for ancestor in current_directory.ancestors() {
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    39
            if ancestor.join(".hg").is_dir() {
46485
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    40
                return Ok(Self::new_at_path(ancestor.to_owned(), config)?);
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    41
            }
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    42
        }
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    43
        Err(RepoFindError::NotFoundInCurrentDirectoryOrAncestors {
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    44
            current_directory,
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    45
        })
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    46
    }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    47
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    48
    /// To be called after checking that `.hg` is a sub-directory
46485
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    49
    fn new_at_path(
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    50
        working_directory: PathBuf,
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    51
        config: &Config,
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    52
    ) -> Result<Self, HgError> {
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    53
        let dot_hg = working_directory.join(".hg");
46463
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    54
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    55
        let hg_vfs = Vfs { base: &dot_hg };
46463
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    56
        let mut reqs = requirements::load_if_exists(hg_vfs)?;
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    57
        let relative =
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    58
            reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT);
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    59
        let shared =
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    60
            reqs.contains(requirements::SHARED_REQUIREMENT) || relative;
46463
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    61
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    62
        // From `mercurial/localrepo.py`:
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    63
        //
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    64
        // if .hg/requires contains the sharesafe requirement, it means
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    65
        // there exists a `.hg/store/requires` too and we should read it
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    66
        // NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    67
        // is present. We never write SHARESAFE_REQUIREMENT for a repo if store
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    68
        // is not present, refer checkrequirementscompat() for that
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    69
        //
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    70
        // However, if SHARESAFE_REQUIREMENT is not present, it means that the
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    71
        // repository was shared the old way. We check the share source
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    72
        // .hg/requires for SHARESAFE_REQUIREMENT to detect whether the
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    73
        // current repository needs to be reshared
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    74
        let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT);
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    75
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    76
        let store_path;
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    77
        if !shared {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    78
            store_path = dot_hg.join("store");
46463
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    79
            if share_safe {
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    80
                reqs.extend(requirements::load(Vfs { base: &store_path })?);
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    81
            }
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    82
        } else {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    83
            let bytes = hg_vfs.read("sharedpath")?;
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    84
            let mut shared_path = get_path_from_bytes(&bytes).to_owned();
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    85
            if relative {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    86
                shared_path = dot_hg.join(shared_path)
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    87
            }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    88
            if !shared_path.is_dir() {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    89
                return Err(HgError::corrupted(format!(
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    90
                    ".hg/sharedpath points to nonexistent directory {}",
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    91
                    shared_path.display()
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    92
                )));
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    93
            }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    94
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    95
            store_path = shared_path.join("store");
46463
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    96
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    97
            let source_is_share_safe =
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    98
                requirements::load(Vfs { base: &shared_path })?
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
    99
                    .contains(requirements::SHARESAFE_REQUIREMENT);
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
   100
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
   101
            if share_safe && !source_is_share_safe {
46485
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   102
                return Err(match config.get(b"safe-mismatch", b"source-not-safe") {
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   103
                    Some(b"abort") | None => HgError::abort(
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   104
                        "share source does not support share-safe requirement"
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   105
                    ),
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   106
                    _ => HgError::unsupported("share-safe downgrade")
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   107
                });
46463
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
   108
            } else if source_is_share_safe && !share_safe {
46485
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   109
                return Err(
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   110
                    match config.get(b"safe-mismatch", b"source-safe") {
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   111
                        Some(b"abort") | None => HgError::abort(
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   112
                            "version mismatch: source uses share-safe \
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   113
                            functionality while the current share does not",
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   114
                        ),
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   115
                        _ => HgError::unsupported("share-safe upgrade"),
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   116
                    },
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   117
                );
46463
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
   118
            }
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   119
        }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   120
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   121
        let repo = Self {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   122
            requirements: reqs,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   123
            working_directory,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   124
            store: store_path,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   125
            dot_hg,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   126
        };
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   127
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   128
        requirements::check(&repo)?;
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   129
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   130
        Ok(repo)
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   131
    }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   132
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   133
    pub fn working_directory_path(&self) -> &Path {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   134
        &self.working_directory
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   135
    }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   136
46462
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   137
    pub fn requirements(&self) -> &HashSet<String> {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   138
        &self.requirements
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   139
    }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
   140
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   141
    /// For accessing repository files (in `.hg`), except for the store
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   142
    /// (`.hg/store`).
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   143
    pub(crate) fn hg_vfs(&self) -> Vfs<'_> {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   144
        Vfs { base: &self.dot_hg }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   145
    }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   146
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   147
    /// For accessing repository store files (in `.hg/store`)
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   148
    pub(crate) fn store_vfs(&self) -> Vfs<'_> {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   149
        Vfs { base: &self.store }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   150
    }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   151
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   152
    /// For accessing the working copy
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   153
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   154
    // The undescore prefix silences the "never used" warning. Remove before
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   155
    // using.
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   156
    pub(crate) fn _working_directory_vfs(&self) -> Vfs<'_> {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   157
        Vfs {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   158
            base: &self.working_directory,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   159
        }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   160
    }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   161
}
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   162
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   163
impl Vfs<'_> {
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   164
    pub(crate) fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf {
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   165
        self.base.join(relative_path)
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   166
    }
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   167
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   168
    pub(crate) fn read(
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   169
        &self,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   170
        relative_path: impl AsRef<Path>,
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46442
diff changeset
   171
    ) -> Result<Vec<u8>, HgError> {
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   172
        let path = self.join(relative_path);
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46442
diff changeset
   173
        std::fs::read(&path).for_file(&path)
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   174
    }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   175
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   176
    pub(crate) fn mmap_open(
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   177
        &self,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   178
        relative_path: impl AsRef<Path>,
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46442
diff changeset
   179
    ) -> Result<Mmap, HgError> {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46442
diff changeset
   180
        let path = self.base.join(relative_path);
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46442
diff changeset
   181
        let file = std::fs::File::open(&path).for_file(&path)?;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   182
        // TODO: what are the safety requirements here?
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46442
diff changeset
   183
        let mmap = unsafe { MmapOptions::new().map(&file) }.for_file(&path)?;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   184
        Ok(mmap)
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   185
    }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   186
}