##// END OF EJS Templates
rhg: Fix status desambiguation of symlinks and executable files...
Simon Sapin -
r49168:d5a91701 default
parent child Browse files
Show More
@@ -580,10 +580,8 b' impl DirstateEntry {'
580 580 &self,
581 581 filesystem_metadata: &std::fs::Metadata,
582 582 ) -> bool {
583 use std::os::unix::fs::MetadataExt;
584 const EXEC_BIT_MASK: u32 = 0o100;
585 let dirstate_exec_bit = (self.mode() as u32) & EXEC_BIT_MASK;
586 let fs_exec_bit = filesystem_metadata.mode() & EXEC_BIT_MASK;
583 let dirstate_exec_bit = (self.mode() as u32 & EXEC_BIT_MASK) != 0;
584 let fs_exec_bit = has_exec_bit(filesystem_metadata);
587 585 dirstate_exec_bit != fs_exec_bit
588 586 }
589 587
@@ -641,3 +639,11 b' impl Into<u8> for EntryState {'
641 639 }
642 640 }
643 641 }
642
643 const EXEC_BIT_MASK: u32 = 0o100;
644
645 pub fn has_exec_bit(metadata: &std::fs::Metadata) -> bool {
646 // TODO: How to handle executable permissions on Windows?
647 use std::os::unix::fs::MetadataExt;
648 (metadata.mode() & EXEC_BIT_MASK) != 0
649 }
@@ -16,6 +16,22 b" impl Vfs<'_> {"
16 16 self.base.join(relative_path)
17 17 }
18 18
19 pub fn symlink_metadata(
20 &self,
21 relative_path: impl AsRef<Path>,
22 ) -> Result<std::fs::Metadata, HgError> {
23 let path = self.join(relative_path);
24 std::fs::symlink_metadata(&path).when_reading_file(&path)
25 }
26
27 pub fn read_link(
28 &self,
29 relative_path: impl AsRef<Path>,
30 ) -> Result<PathBuf, HgError> {
31 let path = self.join(relative_path);
32 std::fs::read_link(&path).when_reading_file(&path)
33 }
34
19 35 pub fn read(
20 36 &self,
21 37 relative_path: impl AsRef<Path>,
@@ -11,11 +11,12 b' use crate::utils::path_utils::relativize'
11 11 use clap::{Arg, SubCommand};
12 12 use hg;
13 13 use hg::config::Config;
14 use hg::dirstate::TruncatedTimestamp;
14 use hg::dirstate::{has_exec_bit, TruncatedTimestamp};
15 15 use hg::errors::HgError;
16 16 use hg::manifest::Manifest;
17 17 use hg::matchers::AlwaysMatcher;
18 18 use hg::repo::Repo;
19 use hg::utils::files::get_bytes_from_os_string;
19 20 use hg::utils::hg_path::{hg_path_to_os_string, HgPath};
20 21 use hg::{HgPathCow, StatusOptions};
21 22 use log::{info, warn};
@@ -302,16 +303,30 b' fn display_status_paths('
302 303 ///
303 304 /// This meant to be used for those that the dirstate cannot resolve, due
304 305 /// to time resolution limits.
305 ///
306 /// TODO: detect permission bits and similar metadata modifications
307 306 fn unsure_is_modified(
308 307 repo: &Repo,
309 308 manifest: &Manifest,
310 309 hg_path: &HgPath,
311 310 ) -> Result<bool, HgError> {
311 let vfs = repo.working_directory_vfs();
312 let fs_path = hg_path_to_os_string(hg_path).expect("HgPath conversion");
313 let fs_metadata = vfs.symlink_metadata(&fs_path)?;
314 let is_symlink = fs_metadata.file_type().is_symlink();
315 // TODO: Also account for `FALLBACK_SYMLINK` and `FALLBACK_EXEC` from the dirstate
316 let fs_flags = if is_symlink {
317 Some(b'l')
318 } else if has_exec_bit(&fs_metadata) {
319 Some(b'x')
320 } else {
321 None
322 };
323
312 324 let entry = manifest
313 325 .find_file(hg_path)?
314 326 .expect("ambgious file not in p1");
327 if entry.flags != fs_flags {
328 return Ok(true);
329 }
315 330 let filelog = repo.filelog(hg_path)?;
316 331 let filelog_entry =
317 332 filelog.data_for_node(entry.node_id()?).map_err(|_| {
@@ -319,7 +334,10 b' fn unsure_is_modified('
319 334 })?;
320 335 let contents_in_p1 = filelog_entry.data()?;
321 336
322 let fs_path = hg_path_to_os_string(hg_path).expect("HgPath conversion");
323 let fs_contents = repo.working_directory_vfs().read(fs_path)?;
337 let fs_contents = if is_symlink {
338 get_bytes_from_os_string(vfs.read_link(fs_path)?.into_os_string())
339 } else {
340 vfs.read(fs_path)?
341 };
324 342 return Ok(contents_in_p1 != &*fs_contents);
325 343 }
@@ -1,9 +1,5 b''
1 1 #require execbit
2 2
3 TODO: fix rhg bugs that make this test fail when status is enabled
4 $ unset RHG_STATUS
5
6
7 3 $ hg init
8 4 $ echo a > a
9 5 $ hg ci -Am'not executable'
@@ -4,10 +4,6 b' Testing merge involving change to the ex'
4 4
5 5 #require execbit
6 6
7 TODO: fix rhg bugs that make this test fail when status is enabled
8 $ unset RHG_STATUS
9
10
11 7 Initial setup
12 8 ==============
13 9
@@ -1,9 +1,5 b''
1 1 #require symlink execbit
2 2
3 TODO: fix rhg bugs that make this test fail when status is enabled
4 $ unset RHG_STATUS
5
6
7 3 $ tellmeabout() {
8 4 > if [ -h $1 ]; then
9 5 > echo $1 is a symlink:
@@ -11,10 +11,6 b''
11 11 > EOF
12 12 #endif
13 13
14 TODO: fix rhg bugs that make this test fail when status is enabled
15 $ unset RHG_STATUS
16
17
18 14 == tests added in 0.7 ==
19 15
20 16 $ hg init test-symlinks-0.7; cd test-symlinks-0.7;
General Comments 0
You need to be logged in to leave comments. Login now