Show More
@@ -380,6 +380,9 b' Node components are:' | |||||
380 | P2_INFO = 1 << 2 |
|
380 | P2_INFO = 1 << 2 | |
381 | HAS_MODE_AND_SIZE = 1 << 3 |
|
381 | HAS_MODE_AND_SIZE = 1 << 3 | |
382 | HAS_MTIME = 1 << 4 |
|
382 | HAS_MTIME = 1 << 4 | |
|
383 | MODE_EXEC_PERM = 1 << 5 | |||
|
384 | MODE_IS_SYMLINK = 1 << 7 | |||
|
385 | ||||
383 |
|
386 | |||
384 | Other bits are unset. The meaning of these bits are: |
|
387 | Other bits are unset. The meaning of these bits are: | |
385 |
|
388 | |||
@@ -414,14 +417,17 b' Node components are:' | |||||
414 | in order to optimize `hg status` |
|
417 | in order to optimize `hg status` | |
415 | by enabling it to skip `readdir` in more cases. |
|
418 | by enabling it to skip `readdir` in more cases. | |
416 |
|
419 | |||
417 |
When a node is for a file tracked anywhere |
|
420 | When a node is for a file tracked anywhere: | |
418 | the rest of the node data is three fields: |
|
421 | - If `HAS_MODE_AND_SIZE` is set, the file is expected | |
|
422 | to be a symbolic link or a normal file based on `MODE_IS_SYMLINK`. | |||
|
423 | - If `HAS_MODE_AND_SIZE` is set, the file’s owner is expected | |||
|
424 | to have execute permission or not based on `MODE_EXEC_PERM`. | |||
|
425 | - If `HAS_MODE_AND_SIZE` is unset, | |||
|
426 | the expected type of file and permission are unknown. | |||
|
427 | The rest of the node data is three fields: | |||
419 |
|
428 | |||
420 | * Offset 31: |
|
429 | * Offset 31: | |
421 | If `HAS_MODE_AND_SIZE` is unset, four zero bytes. |
|
430 | 4 unused bytes, set to zero | |
422 | Otherwise, a 32-bit integer for the Unix mode (as in `stat_result.st_mode`) |
|
|||
423 | expected for this file to be considered clean. |
|
|||
424 | Only the `S_IXUSR` bit (owner has execute permission) is considered. |
|
|||
425 |
|
431 | |||
426 | * Offset 35: |
|
432 | * Offset 35: | |
427 | If `HAS_MODE_AND_SIZE` is unset, four zero bytes. |
|
433 | If `HAS_MODE_AND_SIZE` is unset, four zero bytes. |
@@ -1,5 +1,7 b'' | |||||
1 | # This file is automatically @generated by Cargo. |
|
1 | # This file is automatically @generated by Cargo. | |
2 | # It is not intended for manual editing. |
|
2 | # It is not intended for manual editing. | |
|
3 | version = 3 | |||
|
4 | ||||
3 | [[package]] |
|
5 | [[package]] | |
4 | name = "adler" |
|
6 | name = "adler" | |
5 | version = "0.2.3" |
|
7 | version = "0.2.3" | |
@@ -386,6 +388,7 b' dependencies = [' | |||||
386 | "im-rc", |
|
388 | "im-rc", | |
387 | "itertools", |
|
389 | "itertools", | |
388 | "lazy_static", |
|
390 | "lazy_static", | |
|
391 | "libc", | |||
389 | "log", |
|
392 | "log", | |
390 | "memmap2", |
|
393 | "memmap2", | |
391 | "micro-timer", |
|
394 | "micro-timer", |
@@ -17,6 +17,7 b' home = "0.5"' | |||||
17 | im-rc = "15.0.*" |
|
17 | im-rc = "15.0.*" | |
18 | itertools = "0.9" |
|
18 | itertools = "0.9" | |
19 | lazy_static = "1.4.0" |
|
19 | lazy_static = "1.4.0" | |
|
20 | libc = "0.2" | |||
20 | rand = "0.7.3" |
|
21 | rand = "0.7.3" | |
21 | rand_pcg = "0.2.1" |
|
22 | rand_pcg = "0.2.1" | |
22 | rand_distr = "0.2.2" |
|
23 | rand_distr = "0.2.2" |
@@ -107,13 +107,15 b' bitflags! {' | |||||
107 | const P2_INFO = 1 << 2; |
|
107 | const P2_INFO = 1 << 2; | |
108 | const HAS_MODE_AND_SIZE = 1 << 3; |
|
108 | const HAS_MODE_AND_SIZE = 1 << 3; | |
109 | const HAS_MTIME = 1 << 4; |
|
109 | const HAS_MTIME = 1 << 4; | |
|
110 | const MODE_EXEC_PERM = 1 << 5; | |||
|
111 | const MODE_IS_SYMLINK = 1 << 7; | |||
110 | } |
|
112 | } | |
111 | } |
|
113 | } | |
112 |
|
114 | |||
113 | #[derive(BytesCast, Copy, Clone, Debug)] |
|
115 | #[derive(BytesCast, Copy, Clone, Debug)] | |
114 | #[repr(C)] |
|
116 | #[repr(C)] | |
115 | struct Entry { |
|
117 | struct Entry { | |
116 |
|
|
118 | _padding: U32Be, | |
117 | size: U32Be, |
|
119 | size: U32Be, | |
118 | mtime: U32Be, |
|
120 | mtime: U32Be, | |
119 | } |
|
121 | } | |
@@ -332,13 +334,27 b' impl Node {' | |||||
332 | ) |
|
334 | ) | |
333 | } |
|
335 | } | |
334 |
|
336 | |||
|
337 | fn synthesize_unix_mode(&self) -> u32 { | |||
|
338 | let file_type = if self.flags.contains(Flags::MODE_IS_SYMLINK) { | |||
|
339 | libc::S_IFLNK | |||
|
340 | } else { | |||
|
341 | libc::S_IFREG | |||
|
342 | }; | |||
|
343 | let permisions = if self.flags.contains(Flags::MODE_EXEC_PERM) { | |||
|
344 | 0o755 | |||
|
345 | } else { | |||
|
346 | 0o644 | |||
|
347 | }; | |||
|
348 | file_type | permisions | |||
|
349 | } | |||
|
350 | ||||
335 | fn assume_entry(&self) -> DirstateEntry { |
|
351 | fn assume_entry(&self) -> DirstateEntry { | |
336 | // TODO: convert through raw bits instead? |
|
352 | // TODO: convert through raw bits instead? | |
337 | let wdir_tracked = self.flags.contains(Flags::WDIR_TRACKED); |
|
353 | let wdir_tracked = self.flags.contains(Flags::WDIR_TRACKED); | |
338 | let p1_tracked = self.flags.contains(Flags::P1_TRACKED); |
|
354 | let p1_tracked = self.flags.contains(Flags::P1_TRACKED); | |
339 | let p2_info = self.flags.contains(Flags::P2_INFO); |
|
355 | let p2_info = self.flags.contains(Flags::P2_INFO); | |
340 | let mode_size = if self.flags.contains(Flags::HAS_MODE_AND_SIZE) { |
|
356 | let mode_size = if self.flags.contains(Flags::HAS_MODE_AND_SIZE) { | |
341 |
Some((self. |
|
357 | Some((self.synthesize_unix_mode(), self.data.size.into())) | |
342 | } else { |
|
358 | } else { | |
343 | None |
|
359 | None | |
344 | }; |
|
360 | }; | |
@@ -400,13 +416,15 b' impl Entry {' | |||||
400 | flags.set(Flags::WDIR_TRACKED, wdir_tracked); |
|
416 | flags.set(Flags::WDIR_TRACKED, wdir_tracked); | |
401 | flags.set(Flags::P1_TRACKED, p1_tracked); |
|
417 | flags.set(Flags::P1_TRACKED, p1_tracked); | |
402 | flags.set(Flags::P2_INFO, p2_info); |
|
418 | flags.set(Flags::P2_INFO, p2_info); | |
403 |
let ( |
|
419 | let (size, mtime); | |
404 | if let Some((m, s)) = mode_size_opt { |
|
420 | if let Some((m, s)) = mode_size_opt { | |
405 | mode = m; |
|
421 | let exec_perm = m & libc::S_IXUSR != 0; | |
|
422 | let is_symlink = m & libc::S_IFMT == libc::S_IFLNK; | |||
|
423 | flags.set(Flags::MODE_EXEC_PERM, exec_perm); | |||
|
424 | flags.set(Flags::MODE_IS_SYMLINK, is_symlink); | |||
406 | size = s; |
|
425 | size = s; | |
407 | flags.insert(Flags::HAS_MODE_AND_SIZE) |
|
426 | flags.insert(Flags::HAS_MODE_AND_SIZE) | |
408 | } else { |
|
427 | } else { | |
409 | mode = 0; |
|
|||
410 | size = 0; |
|
428 | size = 0; | |
411 | } |
|
429 | } | |
412 | if let Some(m) = mtime_opt { |
|
430 | if let Some(m) = mtime_opt { | |
@@ -416,7 +434,7 b' impl Entry {' | |||||
416 | mtime = 0; |
|
434 | mtime = 0; | |
417 | } |
|
435 | } | |
418 | let raw_entry = Entry { |
|
436 | let raw_entry = Entry { | |
419 |
|
|
437 | _padding: 0.into(), | |
420 | size: size.into(), |
|
438 | size: size.into(), | |
421 | mtime: mtime.into(), |
|
439 | mtime: mtime.into(), | |
422 | }; |
|
440 | }; | |
@@ -600,7 +618,7 b" impl Writer<'_, '_> {" | |||||
600 | dirstate_map::NodeData::None => ( |
|
618 | dirstate_map::NodeData::None => ( | |
601 | Flags::empty(), |
|
619 | Flags::empty(), | |
602 | Entry { |
|
620 | Entry { | |
603 |
|
|
621 | _padding: 0.into(), | |
604 | size: 0.into(), |
|
622 | size: 0.into(), | |
605 | mtime: 0.into(), |
|
623 | mtime: 0.into(), | |
606 | }, |
|
624 | }, |
@@ -23,7 +23,7 b' python3-bin = ["cpython/python3-sys"]' | |||||
23 | [dependencies] |
|
23 | [dependencies] | |
24 | crossbeam-channel = "0.4" |
|
24 | crossbeam-channel = "0.4" | |
25 | hg-core = { path = "../hg-core"} |
|
25 | hg-core = { path = "../hg-core"} | |
26 |
libc = |
|
26 | libc = "0.2" | |
27 | log = "0.4.8" |
|
27 | log = "0.4.8" | |
28 | env_logger = "0.7.1" |
|
28 | env_logger = "0.7.1" | |
29 | stable_deref_trait = "1.2.0" |
|
29 | stable_deref_trait = "1.2.0" |
General Comments 0
You need to be logged in to leave comments.
Login now