Mercurial > public > mercurial-scm > hg
annotate rust/rhg/src/commands/status.rs @ 49000:dd6b67d5c256 stable
rust: fix unsound `OwningDirstateMap`
As per the previous patch, `OwningDirstateMap` is unsound. Self-referential
structs are difficult to implement correctly in Rust since the compiler is
free to move structs around as much as it wants to. They are also very rarely
needed in practice, so the state-of-the-art on how they should be done within
the Rust rules is still a bit new.
The crate `ouroboros` is an attempt at providing a safe way (in the Rust sense)
of declaring self-referential structs. It is getting a lot attention and was
improved very quickly when soundness issues were found in the past: rather than
relying on our own (limited) review circle, we might as well use the de-facto
common crate to fix this problem. This will give us a much better chance of
finding issues should any new ones be discovered as well as the benefit of
fewer `unsafe` APIs of our own.
I was starting to think about how I would present a safe API to the old struct
but soon realized that the callback-based approach was already done in
`ouroboros`, along with a lot more care towards refusing incorrect structs.
In short: we don't return a mutable reference to the `DirstateMap` anymore, we
expect users of its API to pass a `FnOnce` that takes the map as an argument.
This allows our `OwningDirstateMap` to control the input and output lifetimes
of the code that modifies it to prevent such issues.
Changing to `ouroboros` meant changing every API with it, but it is relatively
low churn in the end. It correctly identified the example buggy modification of
`copy_map_insert` outlined in the previous patch as violating the borrow rules.
Differential Revision: https://phab.mercurial-scm.org/D12429
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Tue, 05 Apr 2022 10:55:28 +0200 |
parents | 00efd2d5037d |
children | 4d3f6767319f |
rev | line source |
---|---|
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
1 // status.rs |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
2 // |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
3 // Copyright 2020, Georges Racinet <georges.racinets@octobus.net> |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
4 // |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
5 // This software may be used and distributed according to the terms of the |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
6 // GNU General Public License version 2 or any later version. |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
7 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
8 use crate::error::CommandError; |
48349
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
9 use crate::ui::Ui; |
48453
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
10 use crate::utils::path_utils::RelativizePaths; |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
11 use clap::{Arg, SubCommand}; |
48349
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
12 use format_bytes::format_bytes; |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
13 use hg; |
48175
707c58880cd0
rhg: add relative paths support in `rhg status`
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48171
diff
changeset
|
14 use hg::config::Config; |
48391
b80e5e75d51e
dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48349
diff
changeset
|
15 use hg::dirstate::has_exec_bit; |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
16 use hg::dirstate::status::StatusPath; |
48422
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
17 use hg::dirstate::TruncatedTimestamp; |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
18 use hg::dirstate::RANGE_MASK_31BIT; |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
19 use hg::errors::{HgError, IoResultExt}; |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
20 use hg::lock::LockError; |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
21 use hg::manifest::Manifest; |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
22 use hg::matchers::AlwaysMatcher; |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
23 use hg::repo::Repo; |
48345
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
24 use hg::utils::files::get_bytes_from_os_string; |
48511
c9abfb80b4e3
rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents:
48501
diff
changeset
|
25 use hg::utils::files::get_bytes_from_path; |
48451
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
26 use hg::utils::files::get_path_from_bytes; |
48422
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
27 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath}; |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
28 use hg::DirstateStatus; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
29 use hg::PatternFileWarning; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
30 use hg::StatusError; |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
31 use hg::StatusOptions; |
48511
c9abfb80b4e3
rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents:
48501
diff
changeset
|
32 use log::info; |
48422
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
33 use std::io; |
48451
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
34 use std::path::PathBuf; |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
35 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
36 pub const HELP_TEXT: &str = " |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
37 Show changed files in the working directory |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
38 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
39 This is a pure Rust version of `hg status`. |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
40 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
41 Some options might be missing, check the list below. |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
42 "; |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
43 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
44 pub fn args() -> clap::App<'static, 'static> { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
45 SubCommand::with_name("status") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
46 .alias("st") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
47 .about(HELP_TEXT) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
48 .arg( |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
49 Arg::with_name("all") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
50 .help("show status of all files") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
51 .short("-A") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
52 .long("--all"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
53 ) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
54 .arg( |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
55 Arg::with_name("modified") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
56 .help("show only modified files") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
57 .short("-m") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
58 .long("--modified"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
59 ) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
60 .arg( |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
61 Arg::with_name("added") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
62 .help("show only added files") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
63 .short("-a") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
64 .long("--added"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
65 ) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
66 .arg( |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
67 Arg::with_name("removed") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
68 .help("show only removed files") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
69 .short("-r") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
70 .long("--removed"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
71 ) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
72 .arg( |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
73 Arg::with_name("clean") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
74 .help("show only clean files") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
75 .short("-c") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
76 .long("--clean"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
77 ) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
78 .arg( |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
79 Arg::with_name("deleted") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
80 .help("show only deleted files") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
81 .short("-d") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
82 .long("--deleted"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
83 ) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
84 .arg( |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
85 Arg::with_name("unknown") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
86 .help("show only unknown (not tracked) files") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
87 .short("-u") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
88 .long("--unknown"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
89 ) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
90 .arg( |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
91 Arg::with_name("ignored") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
92 .help("show only ignored files") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
93 .short("-i") |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
94 .long("--ignored"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
95 ) |
48349
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
96 .arg( |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
97 Arg::with_name("copies") |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
98 .help("show source of copied files (DEFAULT: ui.statuscopies)") |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
99 .short("-C") |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
100 .long("--copies"), |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
101 ) |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
102 .arg( |
48349
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
103 Arg::with_name("no-status") |
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
104 .help("hide status prefix") |
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
105 .short("-n") |
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
106 .long("--no-status"), |
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
107 ) |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
108 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
109 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
110 /// Pure data type allowing the caller to specify file states to display |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
111 #[derive(Copy, Clone, Debug)] |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
112 pub struct DisplayStates { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
113 pub modified: bool, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
114 pub added: bool, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
115 pub removed: bool, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
116 pub clean: bool, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
117 pub deleted: bool, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
118 pub unknown: bool, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
119 pub ignored: bool, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
120 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
121 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
122 pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
123 modified: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
124 added: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
125 removed: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
126 clean: false, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
127 deleted: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
128 unknown: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
129 ignored: false, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
130 }; |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
131 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
132 pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
133 modified: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
134 added: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
135 removed: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
136 clean: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
137 deleted: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
138 unknown: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
139 ignored: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
140 }; |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
141 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
142 impl DisplayStates { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
143 pub fn is_empty(&self) -> bool { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
144 !(self.modified |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
145 || self.added |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
146 || self.removed |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
147 || self.clean |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
148 || self.deleted |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
149 || self.unknown |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
150 || self.ignored) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
151 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
152 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
153 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
154 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> { |
48171
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
155 // TODO: lift these limitations |
48337
3bd62274cbc9
rhg: Propagate config errors in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
48309
diff
changeset
|
156 if invocation.config.get_bool(b"ui", b"tweakdefaults")? { |
48171
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
157 return Err(CommandError::unsupported( |
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
158 "ui.tweakdefaults is not yet supported with rhg status", |
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
159 )); |
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
160 } |
48337
3bd62274cbc9
rhg: Propagate config errors in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
48309
diff
changeset
|
161 if invocation.config.get_bool(b"ui", b"statuscopies")? { |
48171
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
162 return Err(CommandError::unsupported( |
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
163 "ui.statuscopies is not yet supported with rhg status", |
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
164 )); |
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
165 } |
48338
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
166 if invocation |
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
167 .config |
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
168 .get(b"commands", b"status.terse") |
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
169 .is_some() |
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
170 { |
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
171 return Err(CommandError::unsupported( |
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
172 "status.terse is not yet supported with rhg status", |
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
173 )); |
f9db8eeb3aec
rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48337
diff
changeset
|
174 } |
48171
64b8676f11bb
rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48069
diff
changeset
|
175 |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
176 let ui = invocation.ui; |
48175
707c58880cd0
rhg: add relative paths support in `rhg status`
Pulkit Goyal <7895pulkit@gmail.com>
parents:
48171
diff
changeset
|
177 let config = invocation.config; |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
178 let args = invocation.subcommand_args; |
48513
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
179 |
48729
99b1dfc06571
rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents:
48546
diff
changeset
|
180 let verbose = !ui.plain(None) |
48513
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
181 && !args.is_present("print0") |
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
182 && (config.get_bool(b"ui", b"verbose")? |
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
183 || config.get_bool(b"commands", b"status.verbose")?); |
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
184 if verbose { |
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
185 return Err(CommandError::unsupported( |
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
186 "verbose status is not supported yet", |
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
187 )); |
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
188 } |
47f2a82ae3e4
rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents:
48511
diff
changeset
|
189 |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
190 let all = args.is_present("all"); |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
191 let display_states = if all { |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
192 // TODO when implementing `--quiet`: it excludes clean files |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
193 // from `--all` |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
194 ALL_DISPLAY_STATES |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
195 } else { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
196 let requested = DisplayStates { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
197 modified: args.is_present("modified"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
198 added: args.is_present("added"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
199 removed: args.is_present("removed"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
200 clean: args.is_present("clean"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
201 deleted: args.is_present("deleted"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
202 unknown: args.is_present("unknown"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
203 ignored: args.is_present("ignored"), |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
204 }; |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
205 if requested.is_empty() { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
206 DEFAULT_DISPLAY_STATES |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
207 } else { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
208 requested |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
209 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
210 }; |
48349
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
211 let no_status = args.is_present("no-status"); |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
212 let list_copies = all |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
213 || args.is_present("copies") |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
214 || config.get_bool(b"ui", b"statuscopies")?; |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
215 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
216 let repo = invocation.repo?; |
48409
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48391
diff
changeset
|
217 |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48391
diff
changeset
|
218 if repo.has_sparse() || repo.has_narrow() { |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48391
diff
changeset
|
219 return Err(CommandError::unsupported( |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48391
diff
changeset
|
220 "rhg status is not supported for sparse checkouts or narrow clones yet" |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48391
diff
changeset
|
221 )); |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48391
diff
changeset
|
222 } |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48391
diff
changeset
|
223 |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
224 let mut dmap = repo.dirstate_map_mut()?; |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47374
diff
changeset
|
225 |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
226 let options = StatusOptions { |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
227 // we're currently supporting file systems with exec flags only |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
228 // anyway |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
229 check_exec: true, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
230 list_clean: display_states.clean, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
231 list_unknown: display_states.unknown, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
232 list_ignored: display_states.ignored, |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
233 list_copies, |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
234 collect_traversed_dirs: false, |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
235 }; |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
236 |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
237 type StatusResult<'a> = |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
238 Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
239 |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
240 let after_status = |res: StatusResult| -> Result<_, CommandError> { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
241 let (mut ds_status, pattern_warnings) = res?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
242 for warning in pattern_warnings { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
243 match warning { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
244 hg::PatternFileWarning::InvalidSyntax(path, syntax) => ui |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
245 .write_stderr(&format_bytes!( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
246 b"{}: ignoring invalid syntax '{}'\n", |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
247 get_bytes_from_path(path), |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
248 &*syntax |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
249 ))?, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
250 hg::PatternFileWarning::NoSuchFile(path) => { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
251 let path = if let Ok(relative) = |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
252 path.strip_prefix(repo.working_directory_path()) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
253 { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
254 relative |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
255 } else { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
256 &*path |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
257 }; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
258 ui.write_stderr(&format_bytes!( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
259 b"skipping unreadable pattern file '{}': \ |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
260 No such file or directory\n", |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
261 get_bytes_from_path(path), |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
262 ))? |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
263 } |
48511
c9abfb80b4e3
rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents:
48501
diff
changeset
|
264 } |
c9abfb80b4e3
rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents:
48501
diff
changeset
|
265 } |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
266 |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
267 for (path, error) in ds_status.bad { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
268 let error = match error { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
269 hg::BadMatch::OsError(code) => { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
270 std::io::Error::from_raw_os_error(code).to_string() |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
271 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
272 hg::BadMatch::BadType(ty) => { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
273 format!("unsupported file type (type is {})", ty) |
47321
62225f9da938
rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents:
47110
diff
changeset
|
274 } |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
275 }; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
276 ui.write_stderr(&format_bytes!( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
277 b"{}: {}\n", |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
278 path.as_bytes(), |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
279 error.as_bytes() |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
280 ))? |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
281 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
282 if !ds_status.unsure.is_empty() { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
283 info!( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
284 "Files to be rechecked by retrieval from filelog: {:?}", |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
285 ds_status.unsure.iter().map(|s| &s.path).collect::<Vec<_>>() |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
286 ); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
287 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
288 let mut fixup = Vec::new(); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
289 if !ds_status.unsure.is_empty() |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
290 && (display_states.modified || display_states.clean) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
291 { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
292 let p1 = repo.dirstate_parents()?.p1; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
293 let manifest = repo.manifest_for_node(p1).map_err(|e| { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
294 CommandError::from((e, &*format!("{:x}", p1.short()))) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
295 })?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
296 for to_check in ds_status.unsure { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
297 if unsure_is_modified(repo, &manifest, &to_check.path)? { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
298 if display_states.modified { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
299 ds_status.modified.push(to_check); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
300 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
301 } else { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
302 if display_states.clean { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
303 ds_status.clean.push(to_check.clone()); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
304 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
305 fixup.push(to_check.path.into_owned()) |
47321
62225f9da938
rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents:
47110
diff
changeset
|
306 } |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
307 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
308 } |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
309 let relative_paths = (!ui.plain(None)) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
310 && config |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
311 .get_option(b"commands", b"status.relative")? |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
312 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
313 let output = DisplayStatusPaths { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
314 ui, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
315 no_status, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
316 relativize: if relative_paths { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
317 Some(RelativizePaths::new(repo)?) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
318 } else { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
319 None |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
320 }, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
321 }; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
322 if display_states.modified { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
323 output.display(b"M ", "status.modified", ds_status.modified)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
324 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
325 if display_states.added { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
326 output.display(b"A ", "status.added", ds_status.added)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
327 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
328 if display_states.removed { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
329 output.display(b"R ", "status.removed", ds_status.removed)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
330 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
331 if display_states.deleted { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
332 output.display(b"! ", "status.deleted", ds_status.deleted)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
333 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
334 if display_states.unknown { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
335 output.display(b"? ", "status.unknown", ds_status.unknown)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
336 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
337 if display_states.ignored { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
338 output.display(b"I ", "status.ignored", ds_status.ignored)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
339 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
340 if display_states.clean { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
341 output.display(b"C ", "status.clean", ds_status.clean)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
342 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
343 |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
344 let dirstate_write_needed = ds_status.dirty; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
345 let filesystem_time_at_status_start = |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
346 ds_status.filesystem_time_at_status_start; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
347 |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
348 Ok(( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
349 fixup, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
350 dirstate_write_needed, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
351 filesystem_time_at_status_start, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
352 )) |
48452
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
353 }; |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
354 let (fixup, mut dirstate_write_needed, filesystem_time_at_status_start) = |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
355 dmap.with_status( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
356 &AlwaysMatcher, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
357 repo.working_directory_path().to_owned(), |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
358 ignore_files(repo, config), |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
359 options, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
360 after_status, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48738
diff
changeset
|
361 )?; |
48422
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
362 |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
363 if (fixup.is_empty() || filesystem_time_at_status_start.is_none()) |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
364 && !dirstate_write_needed |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
365 { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
366 // Nothing to update |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
367 return Ok(()); |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
368 } |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
369 |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
370 // Update the dirstate on disk if we can |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
371 let with_lock_result = |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
372 repo.try_with_wlock_no_wait(|| -> Result<(), CommandError> { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
373 if let Some(mtime_boundary) = filesystem_time_at_status_start { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
374 for hg_path in fixup { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
375 use std::os::unix::fs::MetadataExt; |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
376 let fs_path = hg_path_to_path_buf(&hg_path) |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
377 .expect("HgPath conversion"); |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
378 // Specifically do not reuse `fs_metadata` from |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
379 // `unsure_is_clean` which was needed before reading |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
380 // contents. Here we access metadata again after reading |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
381 // content, in case it changed in the meantime. |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
382 let fs_metadata = repo |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
383 .working_directory_vfs() |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
384 .symlink_metadata(&fs_path)?; |
48443
112184713852
rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents:
48422
diff
changeset
|
385 if let Some(mtime) = |
112184713852
rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents:
48422
diff
changeset
|
386 TruncatedTimestamp::for_reliable_mtime_of( |
112184713852
rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents:
48422
diff
changeset
|
387 &fs_metadata, |
112184713852
rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents:
48422
diff
changeset
|
388 &mtime_boundary, |
112184713852
rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents:
48422
diff
changeset
|
389 ) |
112184713852
rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents:
48422
diff
changeset
|
390 .when_reading_file(&fs_path)? |
112184713852
rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents:
48422
diff
changeset
|
391 { |
48422
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
392 let mode = fs_metadata.mode(); |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
393 let size = fs_metadata.len() as u32 & RANGE_MASK_31BIT; |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
394 let mut entry = dmap |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
395 .get(&hg_path)? |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
396 .expect("ambiguous file not in dirstate"); |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
397 entry.set_clean(mode, size, mtime); |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
398 dmap.add_file(&hg_path, entry)?; |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
399 dirstate_write_needed = true |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
400 } |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
401 } |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
402 } |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
403 drop(dmap); // Avoid "already mutably borrowed" RefCell panics |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
404 if dirstate_write_needed { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
405 repo.write_dirstate()? |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
406 } |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
407 Ok(()) |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
408 }); |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
409 match with_lock_result { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
410 Ok(closure_result) => closure_result?, |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
411 Err(LockError::AlreadyHeld) => { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
412 // Not updating the dirstate is not ideal but not critical: |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
413 // don’t keep our caller waiting until some other Mercurial |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
414 // process releases the lock. |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
415 } |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
416 Err(LockError::Other(HgError::IoError { error, .. })) |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
417 if error.kind() == io::ErrorKind::PermissionDenied => |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
418 { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
419 // `hg status` on a read-only repository is fine |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
420 } |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
421 Err(LockError::Other(error)) => { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
422 // Report other I/O errors |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
423 Err(error)? |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
424 } |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
425 } |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
426 Ok(()) |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
427 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
428 |
48451
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
429 fn ignore_files(repo: &Repo, config: &Config) -> Vec<PathBuf> { |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
430 let mut ignore_files = Vec::new(); |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
431 let repo_ignore = repo.working_directory_vfs().join(".hgignore"); |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
432 if repo_ignore.exists() { |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
433 ignore_files.push(repo_ignore) |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
434 } |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
435 for (key, value) in config.iter_section(b"ui") { |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
436 if key == b"ignore" || key.starts_with(b"ignore.") { |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
437 let path = get_path_from_bytes(value); |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
438 // TODO:Â expand "~/" and environment variable here, like Python |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
439 // does with `os.path.expanduser` and `os.path.expandvars` |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
440 |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
441 let joined = repo.working_directory_path().join(path); |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
442 ignore_files.push(joined); |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
443 } |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
444 } |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
445 ignore_files |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
446 } |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48443
diff
changeset
|
447 |
48452
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
448 struct DisplayStatusPaths<'a> { |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
449 ui: &'a Ui, |
48349
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
450 no_status: bool, |
48453
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
451 relativize: Option<RelativizePaths>, |
48452
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
452 } |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
453 |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
454 impl DisplayStatusPaths<'_> { |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
455 // Probably more elegant to use a Deref or Borrow trait rather than |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
456 // harcode HgPathBuf, but probably not really useful at this point |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
457 fn display( |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
458 &self, |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
459 status_prefix: &[u8], |
48734
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
460 label: &'static str, |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
461 mut paths: Vec<StatusPath<'_>>, |
48452
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
462 ) -> Result<(), CommandError> { |
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
463 paths.sort_unstable(); |
48738
00efd2d5037d
rust: fix code formatting
Simon Sapin <simon.sapin@octobus.net>
parents:
48735
diff
changeset
|
464 // TODO: get the stdout lock once for the whole loop |
00efd2d5037d
rust: fix code formatting
Simon Sapin <simon.sapin@octobus.net>
parents:
48735
diff
changeset
|
465 // instead of in each write |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
466 for StatusPath { path, copy_source } in paths { |
48453
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
467 let relative; |
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
468 let path = if let Some(relativize) = &self.relativize { |
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
469 relative = relativize.relativize(&path); |
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
470 &*relative |
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
471 } else { |
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
472 path.as_bytes() |
9b0e1f64656f
rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents:
48452
diff
changeset
|
473 }; |
48734
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
474 // TODO: Add a way to use `write_bytes!` instead of `format_bytes!` |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
475 // in order to stream to stdout instead of allocating an |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
476 // itermediate `Vec<u8>`. |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
477 if !self.no_status { |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
478 self.ui.write_stdout_labelled(status_prefix, label)? |
48452
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
479 } |
48734
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
480 self.ui |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
481 .write_stdout_labelled(&format_bytes!(b"{}\n", path), label)?; |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
482 if let Some(source) = copy_source { |
48734
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
483 let label = "status.copied"; |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
484 self.ui.write_stdout_labelled( |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
485 &format_bytes!(b" {}\n", source.as_bytes()), |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
486 label, |
3e2b4bb286e7
rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents:
48729
diff
changeset
|
487 )? |
48454
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48453
diff
changeset
|
488 } |
48349
c12ed33558cb
rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents:
48345
diff
changeset
|
489 } |
48452
2afaa0145584
rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
490 Ok(()) |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
491 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
492 } |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
493 |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
494 /// Check if a file is modified by comparing actual repo store and file system. |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
495 /// |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
496 /// This meant to be used for those that the dirstate cannot resolve, due |
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
497 /// to time resolution limits. |
48344
b6d8eea9872c
rhg: Rename cat_file_is_modified
Simon Sapin <simon.sapin@octobus.net>
parents:
48343
diff
changeset
|
498 fn unsure_is_modified( |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
499 repo: &Repo, |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
500 manifest: &Manifest, |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
501 hg_path: &HgPath, |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
502 ) -> Result<bool, HgError> { |
48345
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
503 let vfs = repo.working_directory_vfs(); |
48422
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
504 let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion"); |
48345
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
505 let fs_metadata = vfs.symlink_metadata(&fs_path)?; |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
506 let is_symlink = fs_metadata.file_type().is_symlink(); |
48391
b80e5e75d51e
dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48349
diff
changeset
|
507 // TODO: Also account for `FALLBACK_SYMLINK` and `FALLBACK_EXEC` from the |
b80e5e75d51e
dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48349
diff
changeset
|
508 // dirstate |
48345
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
509 let fs_flags = if is_symlink { |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
510 Some(b'l') |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
511 } else if has_exec_bit(&fs_metadata) { |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
512 Some(b'x') |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
513 } else { |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
514 None |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
515 }; |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
516 |
48343
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48342
diff
changeset
|
517 let entry = manifest |
48495
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48471
diff
changeset
|
518 .find_by_path(hg_path)? |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
519 .expect("ambgious file not in p1"); |
48345
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
520 if entry.flags != fs_flags { |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
521 return Ok(true); |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
522 } |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
523 let filelog = repo.filelog(hg_path)?; |
48471
b005d07ded7d
rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents:
48467
diff
changeset
|
524 let fs_len = fs_metadata.len(); |
48542
35c47015b9b7
rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents:
48540
diff
changeset
|
525 let filelog_entry = |
35c47015b9b7
rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents:
48540
diff
changeset
|
526 filelog.entry_for_node(entry.node_id()?).map_err(|_| { |
35c47015b9b7
rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents:
48540
diff
changeset
|
527 HgError::corrupted("filelog missing node from manifest") |
35c47015b9b7
rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents:
48540
diff
changeset
|
528 })?; |
48546
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
529 if filelog_entry.file_data_len_not_equal_to(fs_len) { |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
530 // No need to read file contents: |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
531 // it cannot be equal if it has a different length. |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
532 return Ok(true); |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
533 } |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
534 |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
535 let p1_filelog_data = filelog_entry.data()?; |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
536 let p1_contents = p1_filelog_data.file_data()?; |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
537 if p1_contents.len() as u64 != fs_len { |
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
538 // No need to read file contents: |
48471
b005d07ded7d
rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents:
48467
diff
changeset
|
539 // it cannot be equal if it has a different length. |
b005d07ded7d
rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents:
48467
diff
changeset
|
540 return Ok(true); |
b005d07ded7d
rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents:
48467
diff
changeset
|
541 } |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
542 |
48345
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
543 let fs_contents = if is_symlink { |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
544 get_bytes_from_os_string(vfs.read_link(fs_path)?.into_os_string()) |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
545 } else { |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
546 vfs.read(fs_path)? |
d5a91701f7dc
rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents:
48344
diff
changeset
|
547 }; |
48546
e91aa800ae5b
rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents:
48542
diff
changeset
|
548 Ok(p1_contents != &*fs_contents) |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
549 } |