Mercurial > hg
comparison rust/hg-core/src/repo.rs @ 52171:7be39c5110c9
hg-core: add a complete VFS
This will be used from Python in a later change.
More changes are needed in hg-core and rhg to properly clean up the APIs
of the old VFS implementation but it can be done when the dust settles
and we start adding more functionality to the pure Rust VFS.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Mon, 29 Jul 2024 20:47:43 +0200 |
parents | 039b7caeb4d9 |
children | bd8081e9fd62 |
comparison
equal
deleted
inserted
replaced
52170:1a8466fd904a | 52171:7be39c5110c9 |
---|---|
16 use crate::revlog::RevlogError; | 16 use crate::revlog::RevlogError; |
17 use crate::utils::debug::debug_wait_for_file_or_print; | 17 use crate::utils::debug::debug_wait_for_file_or_print; |
18 use crate::utils::files::get_path_from_bytes; | 18 use crate::utils::files::get_path_from_bytes; |
19 use crate::utils::hg_path::HgPath; | 19 use crate::utils::hg_path::HgPath; |
20 use crate::utils::SliceExt; | 20 use crate::utils::SliceExt; |
21 use crate::vfs::{is_dir, is_file, VfsImpl}; | 21 use crate::vfs::{is_dir, is_file, Vfs, VfsImpl}; |
22 use crate::DirstateError; | 22 use crate::DirstateError; |
23 use crate::{ | 23 use crate::{ |
24 exit_codes, requirements, NodePrefix, RevlogType, UncheckedRevision, | 24 exit_codes, requirements, NodePrefix, RevlogType, UncheckedRevision, |
25 }; | 25 }; |
26 use std::cell::{Ref, RefCell, RefMut}; | 26 use std::cell::{Ref, RefCell, RefMut}; |
145 let dot_hg = working_directory.join(".hg"); | 145 let dot_hg = working_directory.join(".hg"); |
146 | 146 |
147 let mut repo_config_files = | 147 let mut repo_config_files = |
148 vec![dot_hg.join("hgrc"), dot_hg.join("hgrc-not-shared")]; | 148 vec![dot_hg.join("hgrc"), dot_hg.join("hgrc-not-shared")]; |
149 | 149 |
150 let hg_vfs = VfsImpl { | 150 let hg_vfs = VfsImpl::new(dot_hg.to_owned(), false); |
151 base: dot_hg.to_owned(), | |
152 }; | |
153 let mut reqs = requirements::load_if_exists(&hg_vfs)?; | 151 let mut reqs = requirements::load_if_exists(&hg_vfs)?; |
154 let relative = | 152 let relative = |
155 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT); | 153 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT); |
156 let shared = | 154 let shared = |
157 reqs.contains(requirements::SHARED_REQUIREMENT) || relative; | 155 reqs.contains(requirements::SHARED_REQUIREMENT) || relative; |
189 .into()); | 187 .into()); |
190 } | 188 } |
191 | 189 |
192 store_path = shared_path.join("store"); | 190 store_path = shared_path.join("store"); |
193 | 191 |
194 let source_is_share_safe = requirements::load(VfsImpl { | 192 let source_is_share_safe = requirements::load(VfsImpl::new( |
195 base: shared_path.to_owned(), | 193 shared_path.to_owned(), |
196 })? | 194 true, |
195 ))? | |
197 .contains(requirements::SHARESAFE_REQUIREMENT); | 196 .contains(requirements::SHARESAFE_REQUIREMENT); |
198 | 197 |
199 if share_safe != source_is_share_safe { | 198 if share_safe != source_is_share_safe { |
200 return Err(HgError::unsupported("share-safe mismatch").into()); | 199 return Err(HgError::unsupported("share-safe mismatch").into()); |
201 } | 200 } |
203 if share_safe { | 202 if share_safe { |
204 repo_config_files.insert(0, shared_path.join("hgrc")) | 203 repo_config_files.insert(0, shared_path.join("hgrc")) |
205 } | 204 } |
206 } | 205 } |
207 if share_safe { | 206 if share_safe { |
208 reqs.extend(requirements::load(VfsImpl { | 207 reqs.extend(requirements::load(VfsImpl::new( |
209 base: store_path.to_owned(), | 208 store_path.to_owned(), |
210 })?); | 209 true, |
210 ))?); | |
211 } | 211 } |
212 | 212 |
213 let repo_config = if std::env::var_os("HGRCSKIPREPO").is_none() { | 213 let repo_config = if std::env::var_os("HGRCSKIPREPO").is_none() { |
214 config.combine_with_repo(&repo_config_files)? | 214 config.combine_with_repo(&repo_config_files)? |
215 } else { | 215 } else { |
246 } | 246 } |
247 | 247 |
248 /// For accessing repository files (in `.hg`), except for the store | 248 /// For accessing repository files (in `.hg`), except for the store |
249 /// (`.hg/store`). | 249 /// (`.hg/store`). |
250 pub fn hg_vfs(&self) -> VfsImpl { | 250 pub fn hg_vfs(&self) -> VfsImpl { |
251 VfsImpl { | 251 VfsImpl::new(self.dot_hg.to_owned(), false) |
252 base: self.dot_hg.to_owned(), | |
253 } | |
254 } | 252 } |
255 | 253 |
256 /// For accessing repository store files (in `.hg/store`) | 254 /// For accessing repository store files (in `.hg/store`) |
257 pub fn store_vfs(&self) -> VfsImpl { | 255 pub fn store_vfs(&self) -> VfsImpl { |
258 VfsImpl { | 256 VfsImpl::new(self.store.to_owned(), false) |
259 base: self.store.to_owned(), | |
260 } | |
261 } | 257 } |
262 | 258 |
263 /// For accessing the working copy | 259 /// For accessing the working copy |
264 pub fn working_directory_vfs(&self) -> VfsImpl { | 260 pub fn working_directory_vfs(&self) -> VfsImpl { |
265 VfsImpl { | 261 VfsImpl::new(self.working_directory.to_owned(), false) |
266 base: self.working_directory.to_owned(), | |
267 } | |
268 } | 262 } |
269 | 263 |
270 pub fn try_with_wlock_no_wait<R>( | 264 pub fn try_with_wlock_no_wait<R>( |
271 &self, | 265 &self, |
272 f: impl FnOnce() -> R, | 266 f: impl FnOnce() -> R, |
793 let vfs = self.hg_vfs(); | 787 let vfs = self.hg_vfs(); |
794 vfs.atomic_write("dirstate", &packed_dirstate)?; | 788 vfs.atomic_write("dirstate", &packed_dirstate)?; |
795 if let Some(uuid) = old_uuid_to_remove { | 789 if let Some(uuid) = old_uuid_to_remove { |
796 // Remove the old data file after the new docket pointing to the | 790 // Remove the old data file after the new docket pointing to the |
797 // new data file was written. | 791 // new data file was written. |
798 vfs.remove_file(format!("dirstate.{}", uuid))?; | 792 vfs.unlink(Path::new(&format!("dirstate.{}", uuid)))?; |
799 } | 793 } |
800 Ok(()) | 794 Ok(()) |
801 } | 795 } |
802 | 796 |
803 pub fn node(&self, rev: UncheckedRevision) -> Option<crate::Node> { | 797 pub fn node(&self, rev: UncheckedRevision) -> Option<crate::Node> { |