rust/rhg/src/commands/status.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 11 Mar 2025 02:29:42 +0100
branchstable
changeset 53042 cdd7bf612c7b
parent 52740 7405f8a67611
permissions -rw-r--r--
bundle-spec: properly format boolean parameter (issue6960) This was breaking automatic clone bundle generation. This changeset fixes it and add a test to catch it in the future.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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;
49981
364e78389653 rust-ui: refactor ui code for printing narrow/sparse warnings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49948
diff changeset
     9
use crate::ui::{
50760
f8412da86d05 rust-config: add support for default config items
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50460
diff changeset
    10
    format_pattern_file_warning, print_narrow_sparse_warnings, relative_paths,
f8412da86d05 rust-config: add support for default config items
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50460
diff changeset
    11
    RelativePaths, Ui,
49981
364e78389653 rust-ui: refactor ui code for printing narrow/sparse warnings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49948
diff changeset
    12
};
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
    13
use crate::utils::path_utils::RelativizePaths;
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    14
use clap::Arg;
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
    15
use format_bytes::format_bytes;
48175
707c58880cd0 rhg: add relative paths support in `rhg status`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48171
diff changeset
    16
use hg::config::Config;
52299
b422acba55f1 rust-dirstate: remove star exports
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52278
diff changeset
    17
use hg::dirstate::entry::{has_exec_bit, TruncatedTimestamp};
52300
04b9a56c2d25 rust-lib: only export very common types to the top of the crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52299
diff changeset
    18
use hg::dirstate::status::{
52301
79e8118cd846 rust-lib: move `Dirstate*Error` to the `dirstate` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52300
diff changeset
    19
    BadMatch, DirstateStatus, StatusError, StatusOptions, StatusPath,
52300
04b9a56c2d25 rust-lib: only export very common types to the top of the crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52299
diff changeset
    20
};
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    21
use hg::errors::{HgError, IoResultExt};
52303
22d24f6d6411 rust-lib: remove exports for not too common pattern-related types
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52301
diff changeset
    22
use hg::filepatterns::{parse_pattern_args, PatternFileWarning};
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    23
use hg::lock::LockError;
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    24
use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    25
use hg::repo::Repo;
52178
bd8081e9fd62 rust: don't star export from the `revlog` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
    26
use hg::revlog::manifest::Manifest;
52156
039b7caeb4d9 rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52033
diff changeset
    27
use hg::revlog::options::{default_revlog_options, RevlogOpenOptions};
52178
bd8081e9fd62 rust: don't star export from the `revlog` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
    28
use hg::revlog::RevlogType;
50215
ae61851e6fe2 dirstate: add a way to test races happening during status
Rapha?l Gom?s <rgomes@octobus.net>, Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50178
diff changeset
    29
use hg::utils::debug::debug_wait_for_file;
50863
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    30
use hg::utils::files::{
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    31
    get_bytes_from_os_str, get_bytes_from_os_string, get_path_from_bytes,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    32
};
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    33
use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
    34
use hg::Revision;
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    35
use hg::{self, narrow, sparse};
48511
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
    36
use log::info;
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
    37
use rayon::prelude::*;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    38
use std::io;
51150
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
    39
use std::mem::take;
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
    40
use std::path::PathBuf;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    41
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    42
pub const HELP_TEXT: &str = "
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    43
Show changed files in the working directory
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    44
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    45
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
    46
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    47
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
    48
";
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    49
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    50
pub fn args() -> clap::Command {
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    51
    clap::command!("status")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    52
        .alias("st")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    53
        .about(HELP_TEXT)
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    54
        .arg(
50863
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    55
            Arg::new("file")
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    56
                .value_parser(clap::value_parser!(std::ffi::OsString))
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    57
                .help("show only these files")
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    58
                .action(clap::ArgAction::Append),
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    59
        )
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50760
diff changeset
    60
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    61
            Arg::new("all")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    62
                .help("show status of all files")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    63
                .short('A')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    64
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    65
                .long("all"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    66
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    67
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    68
            Arg::new("modified")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    69
                .help("show only modified files")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    70
                .short('m')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    71
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    72
                .long("modified"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    73
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    74
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    75
            Arg::new("added")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    76
                .help("show only added files")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    77
                .short('a')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    78
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    79
                .long("added"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    80
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    81
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    82
            Arg::new("removed")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    83
                .help("show only removed files")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    84
                .short('r')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    85
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    86
                .long("removed"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    87
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    88
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    89
            Arg::new("clean")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    90
                .help("show only clean files")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    91
                .short('c')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    92
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    93
                .long("clean"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    94
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    95
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    96
            Arg::new("deleted")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    97
                .help("show only deleted files")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    98
                .short('d')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
    99
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   100
                .long("deleted"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   101
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   102
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   103
            Arg::new("unknown")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   104
                .help("show only unknown (not tracked) files")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   105
                .short('u')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   106
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   107
                .long("unknown"),
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
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   110
            Arg::new("ignored")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   111
                .help("show only ignored files")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   112
                .short('i')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   113
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   114
                .long("ignored"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   115
        )
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   116
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   117
            Arg::new("copies")
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   118
                .help("show source of copied files (DEFAULT: ui.statuscopies)")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   119
                .short('C')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   120
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   121
                .long("copies"),
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   122
        )
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   123
        .arg(
52341
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   124
            Arg::new("no-copies")
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   125
                .action(clap::ArgAction::SetTrue)
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   126
                .long("no-copies")
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   127
                .overrides_with("copies"),
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   128
        )
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   129
        .arg(
50424
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   130
            Arg::new("print0")
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   131
                .help("end filenames with NUL, for use with xargs")
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   132
                .short('0')
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   133
                .action(clap::ArgAction::SetTrue)
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   134
                .long("print0"),
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   135
        )
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   136
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   137
            Arg::new("no-status")
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   138
                .help("hide status prefix")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   139
                .short('n')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   140
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   141
                .long("no-status"),
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   142
        )
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   143
        .arg(
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   144
            Arg::new("verbose")
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   145
                .help("enable additional output")
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   146
                .short('v')
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   147
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   148
                .long("verbose"),
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   149
        )
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   150
        .arg(
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   151
            Arg::new("rev")
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   152
                .help("show difference from/to revision")
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   153
                .long("rev")
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   154
                .num_args(1)
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   155
                .action(clap::ArgAction::Append)
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   156
                .value_name("REV"),
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   157
        )
52398
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   158
        .arg(
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   159
            Arg::new("change")
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   160
                .help("list the changed files of a revision")
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   161
                .long("change")
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   162
                .value_name("REV")
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   163
                .conflicts_with("rev"),
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   164
        )
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   165
}
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   166
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   167
fn parse_revpair(
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   168
    repo: &Repo,
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   169
    revs: Option<Vec<String>>,
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   170
) -> Result<Option<(Revision, Revision)>, CommandError> {
52397
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   171
    let Some(revs) = revs else {
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   172
        return Ok(None);
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   173
    };
52397
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   174
    match revs.as_slice() {
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   175
        [] => Ok(None),
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   176
        [rev1, rev2] => Ok(Some((
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   177
            hg::revset::resolve_single(rev1, repo)?,
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   178
            hg::revset::resolve_single(rev2, repo)?,
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   179
        ))),
42bd36bbed67 hg-core: refactor rev parsing in operations::status_rev_rev
Mitchell Kember <mkember@janestreet.com>
parents: 52395
diff changeset
   180
        _ => Err(CommandError::unsupported("expected 0 or 2 --rev flags")),
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   181
    }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   182
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   183
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   184
/// 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
   185
#[derive(Copy, Clone, Debug)]
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   186
pub struct DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   187
    pub modified: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   188
    pub added: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   189
    pub removed: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   190
    pub clean: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   191
    pub deleted: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   192
    pub unknown: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   193
    pub ignored: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   194
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   195
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   196
pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   197
    modified: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   198
    added: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   199
    removed: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   200
    clean: false,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   201
    deleted: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   202
    unknown: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   203
    ignored: false,
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
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   206
pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   207
    modified: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   208
    added: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   209
    removed: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   210
    clean: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   211
    deleted: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   212
    unknown: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   213
    ignored: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   214
};
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
impl DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   217
    pub fn is_empty(&self) -> bool {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   218
        !(self.modified
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   219
            || self.added
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   220
            || self.removed
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   221
            || self.clean
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   222
            || self.deleted
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   223
            || self.unknown
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   224
            || self.ignored)
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   225
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   226
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   227
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   228
fn has_unfinished_merge(repo: &Repo) -> Result<bool, CommandError> {
49914
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49894
diff changeset
   229
    Ok(repo.dirstate_parents()?.is_merge())
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   230
}
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   231
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   232
fn has_unfinished_state(repo: &Repo) -> Result<bool, CommandError> {
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   233
    // These are all the known values for the [fname] argument of
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   234
    // [addunfinished] function in [state.py]
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   235
    let known_state_files: &[&str] = &[
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   236
        "bisect.state",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   237
        "graftstate",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   238
        "histedit-state",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   239
        "rebasestate",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   240
        "shelvedstate",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   241
        "transplant/journal",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   242
        "updatestate",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   243
    ];
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   244
    if has_unfinished_merge(repo)? {
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   245
        return Ok(true);
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   246
    };
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   247
    for f in known_state_files {
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   248
        if repo.hg_vfs().join(f).exists() {
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   249
            return Ok(true);
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   250
        }
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   251
    }
49914
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49894
diff changeset
   252
    Ok(false)
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   253
}
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   254
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   255
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
   256
    // TODO: lift these limitations
48338
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   257
    if invocation
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   258
        .config
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   259
        .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
   260
        .is_some()
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   261
    {
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   262
        return Err(CommandError::unsupported(
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   263
            "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
   264
        ));
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   265
    }
48171
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   266
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   267
    let ui = invocation.ui;
48175
707c58880cd0 rhg: add relative paths support in `rhg status`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48171
diff changeset
   268
    let config = invocation.config;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   269
    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
   270
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   271
    let revs = args.get_many::<String>("rev");
52398
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   272
    let change = args.get_one::<String>("change");
50424
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   273
    let print0 = args.get_flag("print0");
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   274
    let verbose = args.get_flag("verbose")
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   275
        || config.get_bool(b"ui", b"verbose")?
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   276
        || config.get_bool(b"commands", b"status.verbose")?;
50424
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   277
    let verbose = verbose && !print0;
48513
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   278
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   279
    let all = args.get_flag("all");
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   280
    let display_states = if all {
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   281
        // 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
   282
        // from `--all`
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   283
        ALL_DISPLAY_STATES
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   284
    } else {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   285
        let requested = DisplayStates {
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   286
            modified: args.get_flag("modified"),
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   287
            added: args.get_flag("added"),
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   288
            removed: args.get_flag("removed"),
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   289
            clean: args.get_flag("clean"),
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   290
            deleted: args.get_flag("deleted"),
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   291
            unknown: args.get_flag("unknown"),
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   292
            ignored: args.get_flag("ignored"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   293
        };
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   294
        if requested.is_empty() {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   295
            DEFAULT_DISPLAY_STATES
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   296
        } else {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   297
            requested
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   298
        }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   299
    };
49640
37bc3edef76f rhg: upgrade `clap` dependency
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   300
    let no_status = args.get_flag("no-status");
52341
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   301
    let list_copies = if args.get_flag("copies") {
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   302
        true
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   303
    } else if args.get_flag("no-copies") {
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   304
        false
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   305
    } else {
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   306
        config.get_bool(b"ui", b"statuscopies")?
c2814b698df8 rhg: support rhg status --no-copies
Mitchell Kember <mkember@janestreet.com>
parents: 52303
diff changeset
   307
    };
52342
53dc147bc8b0 rhg: avoid calculating copies for status --no-status
Mitchell Kember <mkember@janestreet.com>
parents: 52341
diff changeset
   308
    let list_copies = (list_copies || all) && !no_status;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   309
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   310
    let repo = invocation.repo?;
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   311
    let revpair = parse_revpair(repo, revs.map(|i| i.cloned().collect()))?;
52398
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   312
    let change = change
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   313
        .map(|rev| hg::revset::resolve_single(rev, repo))
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   314
        .transpose()?;
48409
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   315
49914
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49894
diff changeset
   316
    if verbose && has_unfinished_state(repo)? {
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49894
diff changeset
   317
        return Err(CommandError::unsupported(
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49894
diff changeset
   318
            "verbose status output is not supported by rhg (and is needed because we're in an unfinished operation)",
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49894
diff changeset
   319
        ));
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   320
    }
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   321
47956
81aedf1fc897 rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
   322
    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
   323
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   324
    let check_exec = hg::checkexec::check_exec(repo.working_directory_path());
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   325
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   326
    let options = StatusOptions {
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   327
        check_exec,
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   328
        list_clean: display_states.clean,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   329
        list_unknown: display_states.unknown,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   330
        list_ignored: display_states.ignored,
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   331
        list_copies,
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   332
        collect_traversed_dirs: false,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   333
    };
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   334
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   335
    type StatusResult<'a> =
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   336
        Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   337
51150
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   338
    let relative_status = config
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   339
        .get_option(b"commands", b"status.relative")?
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   340
        .expect("commands.status.relative should have a default value");
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   341
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   342
    let relativize_paths = relative_status || {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   343
        // See in Python code with `getuipathfn` usage in `commands.py`.
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   344
        let legacy_relative_behavior = args.contains_id("file");
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   345
        match relative_paths(invocation.config)? {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   346
            RelativePaths::Legacy => legacy_relative_behavior,
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   347
            RelativePaths::Bool(v) => v,
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   348
        }
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   349
    };
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   350
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   351
    let mut output = DisplayStatusPaths {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   352
        ui,
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   353
        no_status,
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   354
        relativize: if relativize_paths {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   355
            Some(RelativizePaths::new(repo)?)
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   356
        } else {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   357
            None
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   358
        },
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   359
        print0,
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   360
    };
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   361
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   362
    let after_status = |res: StatusResult| -> Result<_, CommandError> {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   363
        let (mut ds_status, pattern_warnings) = res?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   364
        for warning in pattern_warnings {
49981
364e78389653 rust-ui: refactor ui code for printing narrow/sparse warnings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49948
diff changeset
   365
            ui.write_stderr(&format_pattern_file_warning(&warning, repo))?;
48511
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   366
        }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   367
51150
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   368
        for (path, error) in take(&mut ds_status.bad) {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   369
            let error = match error {
52300
04b9a56c2d25 rust-lib: only export very common types to the top of the crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52299
diff changeset
   370
                BadMatch::OsError(code) => {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   371
                    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
   372
                }
52300
04b9a56c2d25 rust-lib: only export very common types to the top of the crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52299
diff changeset
   373
                BadMatch::BadType(ty) => {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   374
                    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
   375
                }
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   376
            };
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   377
            ui.write_stderr(&format_bytes!(
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   378
                b"{}: {}\n",
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   379
                path.as_bytes(),
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   380
                error.as_bytes()
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   381
            ))?
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   382
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   383
        if !ds_status.unsure.is_empty() {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   384
            info!(
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   385
                "Files to be rechecked by retrieval from filelog: {:?}",
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   386
                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
   387
            );
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   388
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   389
        let mut fixup = Vec::new();
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   390
        if !ds_status.unsure.is_empty()
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   391
            && (display_states.modified || display_states.clean)
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   392
        {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   393
            let p1 = repo.dirstate_parents()?.p1;
52343
393ad2685fb4 rust: make RevlogError AmbiguousPrefix case contain the actual prefix
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52342
diff changeset
   394
            let manifest = repo.manifest_for_node(p1)?;
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   395
            let working_directory_vfs = repo.working_directory_vfs();
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   396
            let store_vfs = repo.store_vfs();
52278
51a350a22d0c branching: merge stable into default
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52178 52269
diff changeset
   397
            let filelog_open_options = default_revlog_options(
52156
039b7caeb4d9 rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52033
diff changeset
   398
                repo.config(),
039b7caeb4d9 rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52033
diff changeset
   399
                repo.requirements(),
52278
51a350a22d0c branching: merge stable into default
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52178 52269
diff changeset
   400
                RevlogType::Filelog,
52156
039b7caeb4d9 rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52033
diff changeset
   401
            )?;
51150
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   402
            let res: Vec<_> = take(&mut ds_status.unsure)
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   403
                .into_par_iter()
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   404
                .map(|to_check| {
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   405
                    // The compiler seems to get a bit confused with complex
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   406
                    // inference when using a parallel iterator + map
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   407
                    // + map_err + collect, so let's just inline some of the
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   408
                    // logic.
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   409
                    match unsure_is_modified(
51864
db7dbe6f7bb2 rust: add Vfs trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51863
diff changeset
   410
                        &working_directory_vfs,
db7dbe6f7bb2 rust: add Vfs trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51863
diff changeset
   411
                        &store_vfs,
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   412
                        check_exec,
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   413
                        &manifest,
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   414
                        &to_check.path,
52269
fdecc547a75d rhg-status: rename a variable to be more explicit
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52268
diff changeset
   415
                        filelog_open_options,
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   416
                    ) {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   417
                        Err(HgError::IoError { .. }) => {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   418
                            // IO errors most likely stem from the file being
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   419
                            // deleted even though we know it's in the
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   420
                            // dirstate.
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   421
                            Ok((to_check, UnsureOutcome::Deleted))
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   422
                        }
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   423
                        Ok(outcome) => Ok((to_check, outcome)),
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   424
                        Err(e) => Err(e),
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   425
                    }
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   426
                })
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   427
                .collect::<Result<_, _>>()?;
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   428
            for (status_path, outcome) in res.into_iter() {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   429
                match outcome {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   430
                    UnsureOutcome::Clean => {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   431
                        if display_states.clean {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   432
                            ds_status.clean.push(status_path.clone());
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   433
                        }
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   434
                        fixup.push(status_path.path.into_owned())
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   435
                    }
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   436
                    UnsureOutcome::Modified => {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   437
                        if display_states.modified {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   438
                            ds_status.modified.push(status_path);
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   439
                        }
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   440
                    }
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   441
                    UnsureOutcome::Deleted => {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   442
                        if display_states.deleted {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   443
                            ds_status.deleted.push(status_path);
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   444
                        }
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   445
                    }
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   446
                }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   447
            }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   448
        }
50760
f8412da86d05 rust-config: add support for default config items
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50460
diff changeset
   449
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   450
        let dirstate_write_needed = ds_status.dirty;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   451
        let filesystem_time_at_status_start =
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   452
            ds_status.filesystem_time_at_status_start;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   453
51150
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   454
        output.output(display_states, ds_status)?;
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   455
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   456
        Ok((
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   457
            fixup,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   458
            dirstate_write_needed,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   459
            filesystem_time_at_status_start,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   460
        ))
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   461
    };
52395
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   462
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
   463
    let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?;
52395
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   464
    let (sparse_matcher, sparse_warnings) = sparse::matcher(repo)?;
52740
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   465
    // Sparse is only applicable for the working copy, not history.
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   466
    let sparse_is_applicable = revpair.is_none() && change.is_none();
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   467
    let matcher =
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   468
        match (repo.has_narrow(), repo.has_sparse() && sparse_is_applicable) {
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   469
            (true, true) => Box::new(IntersectionMatcher::new(
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   470
                narrow_matcher,
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   471
                sparse_matcher,
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   472
            )),
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   473
            (true, false) => narrow_matcher,
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   474
            (false, true) => sparse_matcher,
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   475
            (false, false) => Box::new(AlwaysMatcher),
7405f8a67611 rhg: fix status --rev --rev sparse bug
Mitchell Kember <mkember@janestreet.com>
parents: 52726
diff changeset
   476
        };
52395
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   477
    let matcher = match args.get_many::<std::ffi::OsString>("file") {
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   478
        None => matcher,
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   479
        Some(files) => {
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   480
            let patterns: Vec<Vec<u8>> = files
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   481
                .filter(|s| !s.is_empty())
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   482
                .map(get_bytes_from_os_str)
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   483
                .collect();
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   484
            for file in &patterns {
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   485
                if file.starts_with(b"set:") {
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   486
                    return Err(CommandError::unsupported("fileset"));
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   487
                }
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   488
            }
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   489
            let cwd = hg::utils::current_dir()?;
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   490
            let root = repo.working_directory_path();
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   491
            let ignore_patterns = parse_pattern_args(patterns, &cwd, root)?;
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   492
            let files_matcher =
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   493
                hg::matchers::PatternMatcher::new(ignore_patterns)?;
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   494
            Box::new(IntersectionMatcher::new(
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   495
                Box::new(files_matcher),
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   496
                matcher,
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   497
            ))
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   498
        }
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   499
    };
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   500
    print_narrow_sparse_warnings(
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   501
        &narrow_warnings,
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   502
        &sparse_warnings,
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   503
        ui,
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   504
        repo,
136e74c2bf8f rhg: fix bug with matchers in rhg status --rev --rev
Mitchell Kember <mkember@janestreet.com>
parents: 52343
diff changeset
   505
    )?;
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   506
52398
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   507
    if revpair.is_some() || change.is_some() {
51268
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   508
        let mut ds_status = DirstateStatus::default();
52398
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   509
        let list_copies = if list_copies {
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   510
            if config.get_bool(b"devel", b"copy-tracing.trace-all-files")? {
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   511
                Some(hg::operations::ListCopies::AddedOrModified)
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   512
            } else {
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   513
                Some(hg::operations::ListCopies::Added)
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   514
            }
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   515
        } else {
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   516
            None
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   517
        };
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   518
        let stat = if let Some((rev1, rev2)) = revpair {
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   519
            if list_copies.is_some() {
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   520
                return Err(CommandError::unsupported(
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   521
                    "status --rev --rev with copy information is not implemented yet",
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   522
                ));
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   523
            }
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   524
            hg::operations::status_rev_rev_no_copies(
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   525
                repo, rev1, rev2, matcher,
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   526
            )?
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   527
        } else if let Some(rev) = change {
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   528
            hg::operations::status_change(repo, rev, matcher, list_copies)?
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   529
        } else {
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   530
            unreachable!();
bde718849153 rhg: support status --change, including --copies
Mitchell Kember <mkember@janestreet.com>
parents: 52397
diff changeset
   531
        };
51268
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   532
        for entry in stat.iter() {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   533
            let (path, status) = entry?;
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   534
            match status {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   535
                hg::operations::DiffStatus::Removed => {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   536
                    if display_states.removed {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   537
                        ds_status.removed.push(path)
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   538
                    }
51268
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   539
                }
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   540
                hg::operations::DiffStatus::Added => {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   541
                    if display_states.added {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   542
                        ds_status.added.push(path)
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   543
                    }
51268
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   544
                }
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   545
                hg::operations::DiffStatus::Modified => {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   546
                    if display_states.modified {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   547
                        ds_status.modified.push(path)
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   548
                    }
51268
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   549
                }
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   550
                hg::operations::DiffStatus::Matching => {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   551
                    if display_states.clean {
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   552
                        ds_status.clean.push(path)
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   553
                    }
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   554
                }
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   555
            }
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   556
        }
51268
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   557
        output.output(display_states, ds_status)?;
eab5b061cd48 rust-clippy: simplify `match` to `if let`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
   558
        return Ok(());
51152
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   559
    }
ac3859a8b796 rhg: support rhg status --rev --rev
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51150
diff changeset
   560
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   561
    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
   562
        dmap.with_status(
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49483
diff changeset
   563
            matcher.as_ref(),
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   564
            repo.working_directory_path().to_owned(),
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   565
            ignore_files(repo, config),
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   566
            options,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   567
            after_status,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48738
diff changeset
   568
        )?;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   569
50215
ae61851e6fe2 dirstate: add a way to test races happening during status
Rapha?l Gom?s <rgomes@octobus.net>, Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50178
diff changeset
   570
    // Development config option to test write races
ae61851e6fe2 dirstate: add a way to test races happening during status
Rapha?l Gom?s <rgomes@octobus.net>, Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50178
diff changeset
   571
    if let Err(e) =
50252
a6b8b1ab9116 branching: merge stable into default
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50094 50226
diff changeset
   572
        debug_wait_for_file(config, "status.pre-dirstate-write-file")
50215
ae61851e6fe2 dirstate: add a way to test races happening during status
Rapha?l Gom?s <rgomes@octobus.net>, Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50178
diff changeset
   573
    {
ae61851e6fe2 dirstate: add a way to test races happening during status
Rapha?l Gom?s <rgomes@octobus.net>, Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50178
diff changeset
   574
        ui.write_stderr(e.as_bytes()).ok();
ae61851e6fe2 dirstate: add a way to test races happening during status
Rapha?l Gom?s <rgomes@octobus.net>, Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50178
diff changeset
   575
    }
ae61851e6fe2 dirstate: add a way to test races happening during status
Rapha?l Gom?s <rgomes@octobus.net>, Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50178
diff changeset
   576
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   577
    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
   578
        && !dirstate_write_needed
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   579
    {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   580
        // Nothing to update
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   581
        return Ok(());
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   582
    }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   583
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   584
    // 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
   585
    let with_lock_result =
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   586
        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
   587
            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
   588
                for hg_path in fixup {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   589
                    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
   590
                    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
   591
                        .expect("HgPath conversion");
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   592
                    // 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
   593
                    // `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
   594
                    // 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
   595
                    // content, in case it changed in the meantime.
50225
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   596
                    let metadata_res = repo
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   597
                        .working_directory_vfs()
50225
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   598
                        .symlink_metadata(&fs_path);
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   599
                    let fs_metadata = match metadata_res {
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   600
                        Ok(meta) => meta,
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   601
                        Err(err) => match err {
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   602
                            HgError::IoError { .. } => {
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   603
                                // The file has probably been deleted. In any
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   604
                                // case, it was in the dirstate before, so
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   605
                                // let's ignore the error.
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   606
                                continue;
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   607
                            }
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   608
                            _ => return Err(err.into()),
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   609
                        },
53ca3e3bc013 rhg: fix race when a fixup file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50215
diff changeset
   610
                    };
48443
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   611
                    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
   612
                        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
   613
                            &fs_metadata,
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   614
                            &mtime_boundary,
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   615
                        )
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   616
                        .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
   617
                    {
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   618
                        let mode = fs_metadata.mode();
49110
4d3f6767319f rhg: use the new `set_clean` API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49000
diff changeset
   619
                        let size = fs_metadata.len();
4d3f6767319f rhg: use the new `set_clean` API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49000
diff changeset
   620
                        dmap.set_clean(&hg_path, mode, size as u32, mtime)?;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   621
                        dirstate_write_needed = true
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   622
                    }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   623
                }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   624
            }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   625
            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
   626
            if dirstate_write_needed {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   627
                repo.write_dirstate()?
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   628
            }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   629
            Ok(())
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   630
        });
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   631
    match with_lock_result {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   632
        Ok(closure_result) => closure_result?,
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   633
        Err(LockError::AlreadyHeld) => {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   634
            // 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
   635
            // 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
   636
            // process releases the lock.
50178
baa4e2c93642 rust: add debug log about skipping dirstate update
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   637
            log::info!("not writing dirstate from `status`: lock is held")
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   638
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   639
        Err(LockError::Other(HgError::IoError { error, .. }))
51755
955084b4f74f rhg: ignore readonly FS error when saving dirstate
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51747
diff changeset
   640
            if error.kind() == io::ErrorKind::PermissionDenied
955084b4f74f rhg: ignore readonly FS error when saving dirstate
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51747
diff changeset
   641
                || match error.raw_os_error() {
955084b4f74f rhg: ignore readonly FS error when saving dirstate
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51747
diff changeset
   642
                    None => false,
955084b4f74f rhg: ignore readonly FS error when saving dirstate
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51747
diff changeset
   643
                    Some(errno) => libc::EROFS == errno,
955084b4f74f rhg: ignore readonly FS error when saving dirstate
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51747
diff changeset
   644
                } =>
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   645
        {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   646
            // `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
   647
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   648
        Err(LockError::Other(error)) => {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   649
            // Report other I/O errors
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   650
            Err(error)?
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   651
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   652
    }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   653
    Ok(())
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   654
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   655
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   656
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
   657
    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
   658
    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
   659
    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
   660
        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
   661
    }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   662
    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
   663
        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
   664
            let path = get_path_from_bytes(value);
51747
48fd4d23c867 rhg: expand user and environment variables in ignore includes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51268
diff changeset
   665
            let path = shellexpand::path::full_with_context_no_errors(
48fd4d23c867 rhg: expand user and environment variables in ignore includes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51268
diff changeset
   666
                path,
48fd4d23c867 rhg: expand user and environment variables in ignore includes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51268
diff changeset
   667
                home::home_dir,
48fd4d23c867 rhg: expand user and environment variables in ignore includes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51268
diff changeset
   668
                |s| std::env::var(s).ok(),
48fd4d23c867 rhg: expand user and environment variables in ignore includes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51268
diff changeset
   669
            );
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   670
            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
   671
            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
   672
        }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   673
    }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   674
    ignore_files
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   675
}
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   676
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   677
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
   678
    ui: &'a Ui,
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   679
    no_status: bool,
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   680
    relativize: Option<RelativizePaths>,
50424
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   681
    print0: bool,
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   682
}
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   683
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   684
impl DisplayStatusPaths<'_> {
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   685
    // 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
   686
    // 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
   687
    fn display(
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   688
        &self,
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   689
        status_prefix: &[u8],
48734
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   690
        label: &'static str,
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   691
        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
   692
    ) -> Result<(), CommandError> {
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   693
        paths.sort_unstable();
52726
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   694
        let mut stdout = self.ui.stdout_buffer();
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   695
        for StatusPath { path, copy_source } in paths {
50362
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   696
            let relative_path;
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   697
            let relative_source;
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   698
            let (path, copy_source) = if let Some(relativize) =
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   699
                &self.relativize
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   700
            {
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   701
                relative_path = relativize.relativize(&path);
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   702
                relative_source =
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   703
                    copy_source.as_ref().map(|s| relativize.relativize(s));
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   704
                (&*relative_path, relative_source.as_deref())
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   705
            } else {
50362
51041a1a4c59 rhg: correctly relativize copy source path
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 50361
diff changeset
   706
                (path.as_bytes(), copy_source.as_ref().map(|s| s.as_bytes()))
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   707
            };
52726
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   708
            // TODO: Add a way to use `write_bytes!` instead of
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   709
            // `format_bytes!` in order to stream to stdout
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   710
            // instead of allocating an itermediate
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   711
            // `Vec<u8>`.
48734
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   712
            if !self.no_status {
52726
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   713
                stdout.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
   714
            }
50424
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   715
            let linebreak = if self.print0 { b"\x00" } else { b"\n" };
52726
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   716
            stdout.write_stdout_labelled(
50424
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   717
                &format_bytes!(b"{}{}", path, linebreak),
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   718
                label,
98fc949bec14 rhg: support `status --print0`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50252
diff changeset
   719
            )?;
52342
53dc147bc8b0 rhg: avoid calculating copies for status --no-status
Mitchell Kember <mkember@janestreet.com>
parents: 52341
diff changeset
   720
            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
   721
                let label = "status.copied";
52726
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   722
                stdout.write_stdout_labelled(
50460
f57f5ab0e220 branching: merge stable into default
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50424 50362
diff changeset
   723
                    &format_bytes!(b"  {}{}", source, linebreak),
48734
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   724
                    label,
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   725
                )?
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   726
            }
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   727
        }
52726
65839176cea9 rhg: buffer the output of `rhg status`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52398
diff changeset
   728
        stdout.flush()?;
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   729
        Ok(())
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   730
    }
51150
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   731
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   732
    fn output(
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   733
        &mut self,
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   734
        display_states: DisplayStates,
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   735
        ds_status: DirstateStatus,
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   736
    ) -> Result<(), CommandError> {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   737
        if display_states.modified {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   738
            self.display(b"M ", "status.modified", ds_status.modified)?;
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   739
        }
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   740
        if display_states.added {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   741
            self.display(b"A ", "status.added", ds_status.added)?;
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   742
        }
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   743
        if display_states.removed {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   744
            self.display(b"R ", "status.removed", ds_status.removed)?;
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   745
        }
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   746
        if display_states.deleted {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   747
            self.display(b"! ", "status.deleted", ds_status.deleted)?;
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   748
        }
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   749
        if display_states.unknown {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   750
            self.display(b"? ", "status.unknown", ds_status.unknown)?;
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   751
        }
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   752
        if display_states.ignored {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   753
            self.display(b"I ", "status.ignored", ds_status.ignored)?;
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   754
        }
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   755
        if display_states.clean {
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   756
            self.display(b"C ", "status.clean", ds_status.clean)?;
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   757
        }
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   758
        Ok(())
976403c95ba3 rhg: refactor hg status, make the display code usable for non-dirstate status
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50863
diff changeset
   759
    }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   760
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   761
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   762
/// Outcome of the additional check for an ambiguous tracked file
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   763
enum UnsureOutcome {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   764
    /// The file is actually clean
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   765
    Clean,
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   766
    /// The file has been modified
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   767
    Modified,
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   768
    /// The file was deleted on disk (or became another type of fs entry)
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   769
    Deleted,
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   770
}
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   771
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   772
/// 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
   773
///
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   774
/// 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
   775
/// to time resolution limits.
48344
b6d8eea9872c rhg: Rename cat_file_is_modified
Simon Sapin <simon.sapin@octobus.net>
parents: 48343
diff changeset
   776
fn unsure_is_modified(
51864
db7dbe6f7bb2 rust: add Vfs trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51863
diff changeset
   777
    working_directory_vfs: &hg::vfs::VfsImpl,
db7dbe6f7bb2 rust: add Vfs trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51863
diff changeset
   778
    store_vfs: &hg::vfs::VfsImpl,
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   779
    check_exec: bool,
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   780
    manifest: &Manifest,
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   781
    hg_path: &HgPath,
51188
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51152
diff changeset
   782
    revlog_open_options: RevlogOpenOptions,
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   783
) -> Result<UnsureOutcome, HgError> {
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   784
    let vfs = working_directory_vfs;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   785
    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
   786
    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
   787
    let is_symlink = fs_metadata.file_type().is_symlink();
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   788
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   789
    let entry = manifest
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   790
        .find_by_path(hg_path)?
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   791
        .expect("ambgious file not in p1");
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   792
48391
b80e5e75d51e dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48349
diff changeset
   793
    // 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
   794
    // dirstate
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   795
    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
   796
        Some(b'l')
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   797
    } else if check_exec && has_exec_bit(&fs_metadata) {
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   798
        Some(b'x')
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   799
    } else {
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   800
        None
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   801
    };
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   802
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   803
    let entry_flags = if check_exec {
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   804
        entry.flags
52033
0ea323b7e3b1 rust-manifest: encode flags as `Option<NonZeroU8>`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51864
diff changeset
   805
    } else if entry.flags.map(|f| f.into()) == Some(b'x') {
49948
70b4c7af9cdb rust-clippy: fix warning about nested ifs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49914
diff changeset
   806
        None
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   807
    } else {
49948
70b4c7af9cdb rust-clippy: fix warning about nested ifs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49914
diff changeset
   808
        entry.flags
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   809
    };
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49640
diff changeset
   810
52033
0ea323b7e3b1 rust-manifest: encode flags as `Option<NonZeroU8>`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51864
diff changeset
   811
    if entry_flags.map(|f| f.into()) != fs_flags {
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   812
        return Ok(UnsureOutcome::Modified);
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   813
    }
52178
bd8081e9fd62 rust: don't star export from the `revlog` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
   814
    let filelog = hg::revlog::filelog::Filelog::open_vfs(
51864
db7dbe6f7bb2 rust: add Vfs trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51863
diff changeset
   815
        store_vfs,
51188
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51152
diff changeset
   816
        hg_path,
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51152
diff changeset
   817
        revlog_open_options,
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51152
diff changeset
   818
    )?;
48471
b005d07ded7d rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents: 48467
diff changeset
   819
    let fs_len = fs_metadata.len();
49374
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49110
diff changeset
   820
    let file_node = entry.node_id()?;
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49110
diff changeset
   821
    let filelog_entry = filelog.entry_for_node(file_node).map_err(|_| {
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49110
diff changeset
   822
        HgError::corrupted(format!(
50094
1cffc156f7cd rhg: nicer error message
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49981
diff changeset
   823
            "filelog {:?} missing node {:?} from manifest",
1cffc156f7cd rhg: nicer error message
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49981
diff changeset
   824
            hg_path, file_node
49374
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49110
diff changeset
   825
        ))
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49110
diff changeset
   826
    })?;
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   827
    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
   828
        // 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
   829
        // it cannot be equal if it has a different length.
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   830
        return Ok(UnsureOutcome::Modified);
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   831
    }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   832
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   833
    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
   834
    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
   835
    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
   836
        // 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
   837
        // it cannot be equal if it has a different length.
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   838
        return Ok(UnsureOutcome::Modified);
48471
b005d07ded7d rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents: 48467
diff changeset
   839
    }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   840
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   841
    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
   842
        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
   843
    } else {
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   844
        vfs.read(fs_path)?
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   845
    };
50226
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   846
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   847
    Ok(if p1_contents != &*fs_contents {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   848
        UnsureOutcome::Modified
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   849
    } else {
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   850
        UnsureOutcome::Clean
8fcd5302243a rhg: fix race when an ambiguous file is deleted on disk
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50225
diff changeset
   851
    })
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   852
}