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> {