Mercurial > hg-stable
changeset 48265:b874e8d81a98
dirstate-v2: preserve the fallback values on disk
When the fallback values are set, they are now read and written to disk.
See format documentation for details.
Differential Revision: https://phab.mercurial-scm.org/D11688
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 18 Oct 2021 10:56:54 +0200 |
parents | 948570aa7630 |
children | 8c34edb1ad10 |
files | mercurial/helptext/internals/dirstate-v2.txt mercurial/pure/parsers.py rust/hg-core/src/dirstate/entry.rs rust/hg-core/src/dirstate_tree/on_disk.rs |
diffstat | 4 files changed, 102 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/helptext/internals/dirstate-v2.txt Mon Oct 18 20:02:05 2021 +0200 +++ b/mercurial/helptext/internals/dirstate-v2.txt Mon Oct 18 10:56:54 2021 +0200 @@ -386,6 +386,10 @@ EXPECTED_STATE_IS_MODIFIED = 1 << 8 ALL_UNKNOWN_RECORDED = 1 << 9 ALL_IGNORED_RECORDED = 1 << 10 + HAS_FALLBACK_EXEC = 1 << 11 + FALLBACK_EXEC = 1 << 12 + HAS_FALLBACK_SYMLINK = 1 << 13 + FALLBACK_SYMLINK = 1 << 14 The meaning of each bit is described below. @@ -558,3 +562,33 @@ Also note that having this flag unset does not imply that no "ignored" children have been recorded. Some might be present, but there is no garantee that is will be all of them. + +`HAS_FALLBACK_EXEC` + If this flag is set, the entry carries "fallback" information for the + executable bit in the `FALLBACK_EXEC` flag. + + Fallback information can be stored in the dirstate to keep track of + filesystem attribute tracked by Mercurial when the underlying file + system or operating system does not support that property, (e.g. + Windows). + +`FALLBACK_EXEC` + Should be ignored if `HAS_FALLBACK_EXEC` is unset. If set the file for this + entry should be considered executable if that information cannot be + extracted from the file system. If unset it should be considered + non-executable instead. + +`HAS_FALLBACK_SYMLINK` + If this flag is set, the entry carries "fallback" information for symbolic + link status in the `FALLBACK_SYMLINK` flag. + + Fallback information can be stored in the dirstate to keep track of + filesystem attribute tracked by Mercurial when the underlying file + system or operating system does not support that property, (e.g. + Windows). + +`FALLBACK_SYMLINK` + Should be ignored if `HAS_FALLBACK_SYMLINK` is unset. If set the file for + this entry should be considered a symlink if that information cannot be + extracted from the file system. If unset it should be considered a normal + file instead.
--- a/mercurial/pure/parsers.py Mon Oct 18 20:02:05 2021 +0200 +++ b/mercurial/pure/parsers.py Mon Oct 18 10:56:54 2021 +0200 @@ -56,6 +56,10 @@ DIRSTATE_V2_EXPECTED_STATE_IS_MODIFIED = 1 << 8 DIRSTATE_V2_ALL_UNKNOWN_RECORDED = 1 << 9 DIRSTATE_V2_ALL_IGNORED_RECORDED = 1 << 10 +DIRSTATE_V2_HAS_FALLBACK_EXEC = 1 << 11 +DIRSTATE_V2_FALLBACK_EXEC = 1 << 12 +DIRSTATE_V2_HAS_FALLBACK_SYMLINK = 1 << 13 +DIRSTATE_V2_FALLBACK_SYMLINK = 1 << 14 @attr.s(slots=True, init=False) @@ -142,6 +146,14 @@ has_mode_size = False has_meaningful_mtime = False + fallback_exec = None + if flags & DIRSTATE_V2_HAS_FALLBACK_EXEC: + fallback_exec = flags & DIRSTATE_V2_FALLBACK_EXEC + + fallback_symlink = None + if flags & DIRSTATE_V2_HAS_FALLBACK_SYMLINK: + fallback_symlink = flags & DIRSTATE_V2_FALLBACK_SYMLINK + if has_mode_size: assert stat.S_IXUSR == 0o100 if flags & DIRSTATE_V2_MODE_EXEC_PERM: @@ -159,6 +171,8 @@ has_meaningful_data=has_mode_size, has_meaningful_mtime=has_meaningful_mtime, parentfiledata=(mode, size, mtime), + fallback_exec=fallback_exec, + fallback_symlink=fallback_symlink, ) @classmethod @@ -428,6 +442,17 @@ flags |= DIRSTATE_V2_MODE_IS_SYMLINK if self._mtime is not None: flags |= DIRSTATE_V2_HAS_FILE_MTIME + + if self._fallback_exec is not None: + flags |= DIRSTATE_V2_HAS_FALLBACK_EXEC + if self._fallback_exec: + flags |= DIRSTATE_V2_FALLBACK_EXEC + + if self._fallback_symlink is not None: + flags |= DIRSTATE_V2_HAS_FALLBACK_SYMLINK + if self._fallback_symlink: + flags |= DIRSTATE_V2_FALLBACK_SYMLINK + # Note: we do not need to do anything regarding # DIRSTATE_V2_ALL_UNKNOWN_RECORDED and DIRSTATE_V2_ALL_IGNORED_RECORDED # since we never set _DIRSTATE_V2_HAS_DIRCTORY_MTIME
--- a/rust/hg-core/src/dirstate/entry.rs Mon Oct 18 20:02:05 2021 +0200 +++ b/rust/hg-core/src/dirstate/entry.rs Mon Oct 18 10:56:54 2021 +0200 @@ -339,7 +339,15 @@ /// Returns `(wdir_tracked, p1_tracked, p2_info, mode_size, mtime)` pub(crate) fn v2_data( &self, - ) -> (bool, bool, bool, Option<(u32, u32)>, Option<u32>) { + ) -> ( + bool, + bool, + bool, + Option<(u32, u32)>, + Option<u32>, + Option<bool>, + Option<bool>, + ) { if !self.any_tracked() { // TODO: return an Option instead? panic!("Accessing v1_state of an untracked DirstateEntry") @@ -349,7 +357,15 @@ let p2_info = self.flags.contains(Flags::P2_INFO); let mode_size = self.mode_size; let mtime = self.mtime; - (wdir_tracked, p1_tracked, p2_info, mode_size, mtime) + ( + wdir_tracked, + p1_tracked, + p2_info, + mode_size, + mtime, + self.get_fallback_exec(), + self.get_fallback_symlink(), + ) } fn v1_state(&self) -> EntryState {
--- a/rust/hg-core/src/dirstate_tree/on_disk.rs Mon Oct 18 20:02:05 2021 +0200 +++ b/rust/hg-core/src/dirstate_tree/on_disk.rs Mon Oct 18 10:56:54 2021 +0200 @@ -113,6 +113,10 @@ const EXPECTED_STATE_IS_MODIFIED = 1 << 8; const ALL_UNKNOWN_RECORDED = 1 << 9; const ALL_IGNORED_RECORDED = 1 << 10; + const HAS_FALLBACK_EXEC = 1 << 11; + const FALLBACK_EXEC = 1 << 12; + const HAS_FALLBACK_SYMLINK = 1 << 13; + const FALLBACK_SYMLINK = 1 << 14; } } @@ -420,8 +424,15 @@ fn from_dirstate_entry( entry: &DirstateEntry, ) -> (Flags, U32Be, PackedTruncatedTimestamp) { - let (wdir_tracked, p1_tracked, p2_info, mode_size_opt, mtime_opt) = - entry.v2_data(); + let ( + wdir_tracked, + p1_tracked, + p2_info, + mode_size_opt, + mtime_opt, + fallback_exec, + fallback_symlink, + ) = entry.v2_data(); // TODO: convert throug raw flag bits instead? let mut flags = Flags::empty(); flags.set(Flags::WDIR_TRACKED, wdir_tracked); @@ -446,6 +457,18 @@ } else { PackedTruncatedTimestamp::null() }; + if let Some(f_exec) = fallback_exec { + flags.insert(Flags::HAS_FALLBACK_EXEC); + if f_exec { + flags.insert(Flags::FALLBACK_EXEC); + } + } + if let Some(f_symlink) = fallback_symlink { + flags.insert(Flags::HAS_FALLBACK_SYMLINK); + if f_symlink { + flags.insert(Flags::FALLBACK_SYMLINK); + } + } (flags, size, mtime) } }