rust/rhg/src/commands/status.rs
author Raphaël Gomès <rgomes@octobus.net>
Wed, 25 Jan 2023 18:44:09 +0100
changeset 49952 70b4c7af9cdb
parent 49914 58074252db3c
child 49981 364e78389653
permissions -rw-r--r--
rust-clippy: fix warning about nested ifs
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;
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
     9
use crate::ui::Ui;
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
    10
use crate::utils::path_utils::RelativizePaths;
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    11
use clap::Arg;
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
    12
use format_bytes::format_bytes;
48175
707c58880cd0 rhg: add relative paths support in `rhg status`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48171
diff changeset
    13
use hg::config::Config;
48391
b80e5e75d51e dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48349
diff changeset
    14
use hg::dirstate::has_exec_bit;
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    15
use hg::dirstate::status::StatusPath;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    16
use hg::dirstate::TruncatedTimestamp;
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    17
use hg::errors::{HgError, IoResultExt};
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    18
use hg::lock::LockError;
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
    19
use hg::manifest::Manifest;
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    20
use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    21
use hg::repo::Repo;
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
    22
use hg::utils::files::get_bytes_from_os_string;
48511
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
    23
use hg::utils::files::get_bytes_from_path;
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
    24
use hg::utils::files::get_path_from_bytes;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    25
use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
    26
use hg::DirstateStatus;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
    27
use hg::PatternFileWarning;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
    28
use hg::StatusError;
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    29
use hg::StatusOptions;
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
    30
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
    31
use log::info;
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
    32
use rayon::prelude::*;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    33
use std::io;
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
    34
use std::path::PathBuf;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    35
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    36
pub const HELP_TEXT: &str = "
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    37
Show changed files in the working directory
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    38
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    39
This is a pure Rust version of `hg status`.
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    40
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    41
Some options might be missing, check the list below.
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    42
";
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    43
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    44
pub fn args() -> clap::Command {
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    45
    clap::command!("status")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    46
        .alias("st")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    47
        .about(HELP_TEXT)
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    48
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    49
            Arg::new("all")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    50
                .help("show status of all files")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    51
                .short('A')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    52
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    53
                .long("all"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    54
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    55
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    56
            Arg::new("modified")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    57
                .help("show only modified files")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    58
                .short('m')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    59
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    60
                .long("modified"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    61
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    62
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    63
            Arg::new("added")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    64
                .help("show only added files")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    65
                .short('a')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    66
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    67
                .long("added"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    68
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    69
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    70
            Arg::new("removed")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    71
                .help("show only removed files")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    72
                .short('r')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    73
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    74
                .long("removed"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    75
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    76
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    77
            Arg::new("clean")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    78
                .help("show only clean files")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    79
                .short('c')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    80
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    81
                .long("clean"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    82
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    83
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    84
            Arg::new("deleted")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    85
                .help("show only deleted files")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    86
                .short('d')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    87
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    88
                .long("deleted"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    89
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    90
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    91
            Arg::new("unknown")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    92
                .help("show only unknown (not tracked) files")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    93
                .short('u')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    94
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    95
                .long("unknown"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    96
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    97
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
    98
            Arg::new("ignored")
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    99
                .help("show only ignored files")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   100
                .short('i')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   101
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   102
                .long("ignored"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   103
        )
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   104
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   105
            Arg::new("copies")
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   106
                .help("show source of copied files (DEFAULT: ui.statuscopies)")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   107
                .short('C')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   108
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   109
                .long("copies"),
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   110
        )
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   111
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   112
            Arg::new("no-status")
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   113
                .help("hide status prefix")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   114
                .short('n')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   115
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   116
                .long("no-status"),
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   117
        )
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   118
        .arg(
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   119
            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
   120
                .help("enable additional output")
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   121
                .short('v')
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   122
                .action(clap::ArgAction::SetTrue)
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   123
                .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
   124
        )
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   125
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   126
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   127
/// 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
   128
#[derive(Copy, Clone, Debug)]
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   129
pub struct DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   130
    pub modified: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   131
    pub added: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   132
    pub removed: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   133
    pub clean: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   134
    pub deleted: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   135
    pub unknown: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   136
    pub ignored: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   137
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   138
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   139
pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   140
    modified: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   141
    added: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   142
    removed: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   143
    clean: false,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   144
    deleted: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   145
    unknown: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   146
    ignored: false,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   147
};
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   148
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   149
pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   150
    modified: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   151
    added: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   152
    removed: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   153
    clean: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   154
    deleted: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   155
    unknown: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   156
    ignored: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   157
};
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   158
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   159
impl DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   160
    pub fn is_empty(&self) -> bool {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   161
        !(self.modified
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   162
            || self.added
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   163
            || self.removed
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   164
            || self.clean
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   165
            || self.deleted
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   166
            || self.unknown
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   167
            || self.ignored)
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   168
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   169
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   170
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   171
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
   172
    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
   173
}
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   174
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   175
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
   176
    // 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
   177
    // [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
   178
    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
   179
        "bisect.state",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   180
        "graftstate",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   181
        "histedit-state",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   182
        "rebasestate",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   183
        "shelvedstate",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   184
        "transplant/journal",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   185
        "updatestate",
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   186
    ];
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   187
    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
   188
        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
   189
    };
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   190
    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
   191
        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
   192
            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
   193
        }
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   194
    }
49914
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49894
diff changeset
   195
    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
   196
}
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   197
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   198
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
   199
    // TODO: lift these limitations
48338
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   200
    if invocation
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   201
        .config
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   202
        .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
   203
        .is_some()
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   204
    {
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   205
        return Err(CommandError::unsupported(
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   206
            "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
   207
        ));
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   208
    }
48171
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   209
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   210
    let ui = invocation.ui;
48175
707c58880cd0 rhg: add relative paths support in `rhg status`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48171
diff changeset
   211
    let config = invocation.config;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   212
    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
   213
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   214
    // TODO add `!args.get_flag("print0") &&` when we support `print0`
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   215
    let verbose = args.get_flag("verbose")
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   216
        || config.get_bool(b"ui", b"verbose")?
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   217
        || config.get_bool(b"commands", b"status.verbose")?;
48513
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   218
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   219
    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
   220
    let display_states = if all {
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   221
        // 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
   222
        // from `--all`
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   223
        ALL_DISPLAY_STATES
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   224
    } else {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   225
        let requested = DisplayStates {
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   226
            modified: args.get_flag("modified"),
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   227
            added: args.get_flag("added"),
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   228
            removed: args.get_flag("removed"),
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   229
            clean: args.get_flag("clean"),
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   230
            deleted: args.get_flag("deleted"),
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   231
            unknown: args.get_flag("unknown"),
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   232
            ignored: args.get_flag("ignored"),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   233
        };
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   234
        if requested.is_empty() {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   235
            DEFAULT_DISPLAY_STATES
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   236
        } else {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   237
            requested
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   238
        }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   239
    };
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   240
    let no_status = args.get_flag("no-status");
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   241
    let list_copies = all
49639
37bc3edef76f rhg: upgrade `clap` dependency
Raphaël Gomès <rgomes@octobus.net>
parents: 49517
diff changeset
   242
        || args.get_flag("copies")
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   243
        || config.get_bool(b"ui", b"statuscopies")?;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   244
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   245
    let repo = invocation.repo?;
48409
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   246
49914
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49894
diff changeset
   247
    if verbose && has_unfinished_state(repo)? {
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49894
diff changeset
   248
        return Err(CommandError::unsupported(
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49894
diff changeset
   249
            "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
   250
        ));
49439
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   251
    }
b07465adbcc8 rhg: make [rhg status -v] work when it needs no extra output
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49374
diff changeset
   252
47956
81aedf1fc897 rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
   253
    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
   254
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   255
    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: 49639
diff changeset
   256
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   257
    let options = StatusOptions {
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   258
        check_exec,
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   259
        list_clean: display_states.clean,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   260
        list_unknown: display_states.unknown,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   261
        list_ignored: display_states.ignored,
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   262
        list_copies,
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   263
        collect_traversed_dirs: false,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   264
    };
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   265
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   266
    type StatusResult<'a> =
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   267
        Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   268
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   269
    let after_status = |res: StatusResult| -> Result<_, CommandError> {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   270
        let (mut ds_status, pattern_warnings) = res?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   271
        for warning in pattern_warnings {
49914
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49894
diff changeset
   272
            ui.write_stderr(&print_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
   273
        }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   274
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   275
        for (path, error) in ds_status.bad {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   276
            let error = match error {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   277
                hg::BadMatch::OsError(code) => {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   278
                    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
   279
                }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   280
                hg::BadMatch::BadType(ty) => {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   281
                    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
   282
                }
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   283
            };
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   284
            ui.write_stderr(&format_bytes!(
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   285
                b"{}: {}\n",
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   286
                path.as_bytes(),
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   287
                error.as_bytes()
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   288
            ))?
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   289
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   290
        if !ds_status.unsure.is_empty() {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   291
            info!(
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   292
                "Files to be rechecked by retrieval from filelog: {:?}",
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   293
                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
   294
            );
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   295
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   296
        let mut fixup = Vec::new();
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   297
        if !ds_status.unsure.is_empty()
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   298
            && (display_states.modified || display_states.clean)
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   299
        {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   300
            let p1 = repo.dirstate_parents()?.p1;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   301
            let manifest = repo.manifest_for_node(p1).map_err(|e| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   302
                CommandError::from((e, &*format!("{:x}", p1.short())))
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   303
            })?;
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   304
            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
   305
            let store_vfs = repo.store_vfs();
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   306
            let res: Vec<_> = ds_status
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   307
                .unsure
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   308
                .into_par_iter()
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   309
                .map(|to_check| {
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   310
                    unsure_is_modified(
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   311
                        working_directory_vfs,
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   312
                        store_vfs,
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   313
                        check_exec,
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   314
                        &manifest,
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   315
                        &to_check.path,
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   316
                    )
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   317
                    .map(|modified| (to_check, modified))
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   318
                })
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   319
                .collect::<Result<_, _>>()?;
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   320
            for (status_path, is_modified) in res.into_iter() {
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   321
                if is_modified {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   322
                    if display_states.modified {
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   323
                        ds_status.modified.push(status_path);
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   324
                    }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   325
                } else {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   326
                    if display_states.clean {
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   327
                        ds_status.clean.push(status_path.clone());
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   328
                    }
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   329
                    fixup.push(status_path.path.into_owned())
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   330
                }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   331
            }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   332
        }
49512
6939d5ed20e0 rhg: central treatment of PLAIN and PLAINEXCEPT
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49488
diff changeset
   333
        let relative_paths = config
6939d5ed20e0 rhg: central treatment of PLAIN and PLAINEXCEPT
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49488
diff changeset
   334
            .get_option(b"commands", b"status.relative")?
6939d5ed20e0 rhg: central treatment of PLAIN and PLAINEXCEPT
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49488
diff changeset
   335
            .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   336
        let output = DisplayStatusPaths {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   337
            ui,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   338
            no_status,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   339
            relativize: if relative_paths {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   340
                Some(RelativizePaths::new(repo)?)
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   341
            } else {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   342
                None
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   343
            },
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   344
        };
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   345
        if display_states.modified {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   346
            output.display(b"M ", "status.modified", ds_status.modified)?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   347
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   348
        if display_states.added {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   349
            output.display(b"A ", "status.added", ds_status.added)?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   350
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   351
        if display_states.removed {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   352
            output.display(b"R ", "status.removed", ds_status.removed)?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   353
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   354
        if display_states.deleted {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   355
            output.display(b"! ", "status.deleted", ds_status.deleted)?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   356
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   357
        if display_states.unknown {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   358
            output.display(b"? ", "status.unknown", ds_status.unknown)?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   359
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   360
        if display_states.ignored {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   361
            output.display(b"I ", "status.ignored", ds_status.ignored)?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   362
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   363
        if display_states.clean {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   364
            output.display(b"C ", "status.clean", ds_status.clean)?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   365
        }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   366
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   367
        let dirstate_write_needed = ds_status.dirty;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   368
        let filesystem_time_at_status_start =
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   369
            ds_status.filesystem_time_at_status_start;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   370
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   371
        Ok((
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   372
            fixup,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   373
            dirstate_write_needed,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   374
            filesystem_time_at_status_start,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   375
        ))
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   376
    };
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   377
    let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?;
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   378
    let (sparse_matcher, sparse_warnings) = sparse::matcher(repo)?;
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   379
    let matcher = match (repo.has_narrow(), repo.has_sparse()) {
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   380
        (true, true) => {
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   381
            Box::new(IntersectionMatcher::new(narrow_matcher, sparse_matcher))
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   382
        }
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   383
        (true, false) => narrow_matcher,
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   384
        (false, true) => sparse_matcher,
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   385
        (false, false) => Box::new(AlwaysMatcher),
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   386
    };
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   387
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   388
    for warning in narrow_warnings.into_iter().chain(sparse_warnings) {
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   389
        match &warning {
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   390
            sparse::SparseWarning::RootWarning { context, line } => {
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   391
                let msg = format_bytes!(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   392
                    b"warning: {} profile cannot use paths \"
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   393
                    starting with /, ignoring {}\n",
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   394
                    context,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   395
                    line
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   396
                );
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   397
                ui.write_stderr(&msg)?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   398
            }
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   399
            sparse::SparseWarning::ProfileNotFound { profile, rev } => {
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   400
                let msg = format_bytes!(
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   401
                    b"warning: sparse profile '{}' not found \"
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   402
                    in rev {} - ignoring it\n",
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   403
                    profile,
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   404
                    rev
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   405
                );
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   406
                ui.write_stderr(&msg)?;
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   407
            }
49488
7c93e38a0bbd rhg-status: add support for narrow clones
Raphaël Gomès <rgomes@octobus.net>
parents: 49485
diff changeset
   408
            sparse::SparseWarning::Pattern(e) => {
49914
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49894
diff changeset
   409
                ui.write_stderr(&print_pattern_file_warning(e, repo))?;
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   410
            }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   411
        }
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   412
    }
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   413
    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
   414
        dmap.with_status(
49485
ffd4b1f1c9cb rhg: add sparse support
Raphaël Gomès <rgomes@octobus.net>
parents: 49483
diff changeset
   415
            matcher.as_ref(),
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   416
            repo.working_directory_path().to_owned(),
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   417
            ignore_files(repo, config),
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   418
            options,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   419
            after_status,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48738
diff changeset
   420
        )?;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   421
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   422
    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
   423
        && !dirstate_write_needed
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   424
    {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   425
        // Nothing to update
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   426
        return Ok(());
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   427
    }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   428
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   429
    // 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
   430
    let with_lock_result =
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   431
        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
   432
            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
   433
                for hg_path in fixup {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   434
                    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
   435
                    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
   436
                        .expect("HgPath conversion");
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   437
                    // 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
   438
                    // `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
   439
                    // 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
   440
                    // content, in case it changed in the meantime.
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   441
                    let fs_metadata = repo
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   442
                        .working_directory_vfs()
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   443
                        .symlink_metadata(&fs_path)?;
48443
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   444
                    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
   445
                        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
   446
                            &fs_metadata,
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   447
                            &mtime_boundary,
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   448
                        )
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   449
                        .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
   450
                    {
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   451
                        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
   452
                        let size = fs_metadata.len();
4d3f6767319f rhg: use the new `set_clean` API
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
   453
                        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
   454
                        dirstate_write_needed = true
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   455
                    }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   456
                }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   457
            }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   458
            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
   459
            if dirstate_write_needed {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   460
                repo.write_dirstate()?
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   461
            }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   462
            Ok(())
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   463
        });
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   464
    match with_lock_result {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   465
        Ok(closure_result) => closure_result?,
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   466
        Err(LockError::AlreadyHeld) => {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   467
            // 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
   468
            // 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
   469
            // process releases the lock.
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   470
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   471
        Err(LockError::Other(HgError::IoError { error, .. }))
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   472
            if error.kind() == io::ErrorKind::PermissionDenied =>
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   473
        {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   474
            // `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
   475
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   476
        Err(LockError::Other(error)) => {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   477
            // Report other I/O errors
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   478
            Err(error)?
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   479
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   480
    }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   481
    Ok(())
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   482
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   483
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   484
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
   485
    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
   486
    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
   487
    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
   488
        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
   489
    }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   490
    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
   491
        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
   492
            let path = get_path_from_bytes(value);
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   493
            // TODO: expand "~/" and environment variable here, like Python
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   494
            // does with `os.path.expanduser` and `os.path.expandvars`
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   495
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   496
            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
   497
            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
   498
        }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   499
    }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   500
    ignore_files
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   501
}
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   502
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   503
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
   504
    ui: &'a Ui,
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   505
    no_status: bool,
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   506
    relativize: Option<RelativizePaths>,
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   507
}
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   508
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   509
impl DisplayStatusPaths<'_> {
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   510
    // 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
   511
    // 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
   512
    fn display(
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   513
        &self,
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   514
        status_prefix: &[u8],
48734
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   515
        label: &'static str,
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   516
        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
   517
    ) -> Result<(), CommandError> {
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   518
        paths.sort_unstable();
48738
00efd2d5037d rust: fix code formatting
Simon Sapin <simon.sapin@octobus.net>
parents: 48735
diff changeset
   519
        // TODO: get the stdout lock once for the whole loop
00efd2d5037d rust: fix code formatting
Simon Sapin <simon.sapin@octobus.net>
parents: 48735
diff changeset
   520
        // instead of in each write
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   521
        for StatusPath { path, copy_source } in paths {
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   522
            let relative;
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   523
            let path = if let Some(relativize) = &self.relativize {
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   524
                relative = relativize.relativize(&path);
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   525
                &*relative
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   526
            } else {
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   527
                path.as_bytes()
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   528
            };
48734
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   529
            // TODO: Add a way to use `write_bytes!` instead of `format_bytes!`
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   530
            // in order to stream to stdout instead of allocating an
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   531
            // itermediate `Vec<u8>`.
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   532
            if !self.no_status {
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   533
                self.ui.write_stdout_labelled(status_prefix, label)?
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   534
            }
48734
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   535
            self.ui
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   536
                .write_stdout_labelled(&format_bytes!(b"{}\n", path), label)?;
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   537
            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
   538
                let label = "status.copied";
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   539
                self.ui.write_stdout_labelled(
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   540
                    &format_bytes!(b"  {}\n", source.as_bytes()),
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   541
                    label,
3e2b4bb286e7 rhg: Colorize `rhg status` output when appropriate
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
   542
                )?
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   543
            }
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   544
        }
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   545
        Ok(())
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   546
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   547
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   548
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   549
/// 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
   550
///
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   551
/// 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
   552
/// to time resolution limits.
48344
b6d8eea9872c rhg: Rename cat_file_is_modified
Simon Sapin <simon.sapin@octobus.net>
parents: 48343
diff changeset
   553
fn unsure_is_modified(
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   554
    working_directory_vfs: hg::vfs::Vfs,
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   555
    store_vfs: hg::vfs::Vfs,
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   556
    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
   557
    manifest: &Manifest,
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   558
    hg_path: &HgPath,
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   559
) -> Result<bool, HgError> {
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   560
    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
   561
    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
   562
    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
   563
    let is_symlink = fs_metadata.file_type().is_symlink();
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   564
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   565
    let entry = manifest
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   566
        .find_by_path(hg_path)?
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   567
        .expect("ambgious file not in p1");
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   568
48391
b80e5e75d51e dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48349
diff changeset
   569
    // 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
   570
    // dirstate
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   571
    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
   572
        Some(b'l')
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   573
    } 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
   574
        Some(b'x')
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   575
    } else {
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   576
        None
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   577
    };
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   578
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   579
    let entry_flags = if check_exec {
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   580
        entry.flags
49952
70b4c7af9cdb rust-clippy: fix warning about nested ifs
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   581
    } else if entry.flags == Some(b'x') {
70b4c7af9cdb rust-clippy: fix warning about nested ifs
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   582
        None
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   583
    } else {
49952
70b4c7af9cdb rust-clippy: fix warning about nested ifs
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   584
        entry.flags
49894
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   585
    };
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   586
678588b01af1 rhg: implement checkexec to support weird filesystems
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49639
diff changeset
   587
    if entry_flags != fs_flags {
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   588
        return Ok(true);
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   589
    }
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49516
diff changeset
   590
    let filelog = hg::filelog::Filelog::open_vfs(&store_vfs, hg_path)?;
48471
b005d07ded7d rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents: 48467
diff changeset
   591
    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
   592
    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
   593
    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
   594
        HgError::corrupted(format!(
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 49110
diff changeset
   595
            "filelog missing node {:?} from manifest",
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 49110
diff changeset
   596
            file_node
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 49110
diff changeset
   597
        ))
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 49110
diff changeset
   598
    })?;
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   599
    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
   600
        // 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
   601
        // it cannot be equal if it has a different length.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   602
        return Ok(true);
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   603
    }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   604
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   605
    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
   606
    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
   607
    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
   608
        // 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
   609
        // it cannot be equal if it has a different length.
b005d07ded7d rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents: 48467
diff changeset
   610
        return Ok(true);
b005d07ded7d rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents: 48467
diff changeset
   611
    }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   612
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   613
    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
   614
        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
   615
    } else {
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   616
        vfs.read(fs_path)?
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   617
    };
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   618
    Ok(p1_contents != &*fs_contents)
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   619
}
49483
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   620
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   621
fn print_pattern_file_warning(
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   622
    warning: &PatternFileWarning,
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   623
    repo: &Repo,
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   624
) -> Vec<u8> {
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   625
    match warning {
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   626
        PatternFileWarning::InvalidSyntax(path, syntax) => format_bytes!(
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   627
            b"{}: ignoring invalid syntax '{}'\n",
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   628
            get_bytes_from_path(path),
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   629
            &*syntax
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   630
        ),
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   631
        PatternFileWarning::NoSuchFile(path) => {
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   632
            let path = if let Ok(relative) =
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   633
                path.strip_prefix(repo.working_directory_path())
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   634
            {
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   635
                relative
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   636
            } else {
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   637
                &*path
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   638
            };
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   639
            format_bytes!(
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   640
                b"skipping unreadable pattern file '{}': \
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   641
                    No such file or directory\n",
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   642
                get_bytes_from_path(path),
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   643
            )
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   644
        }
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   645
    }
b18e877ea304 rhg-status: extract a function for printing pattern file warnings
Raphaël Gomès <rgomes@octobus.net>
parents: 49439
diff changeset
   646
}