rust/rhg/src/commands/status.rs
author Simon Sapin <simon.sapin@octobus.net>
Fri, 07 Jan 2022 14:40:21 +0100
changeset 48546 e91aa800ae5b
parent 48542 35c47015b9b7
child 48729 99b1dfc06571
permissions -rw-r--r--
rhg: desambiguate status without decompressing filelog if possible When status is unsure based on `stat()` and the dirstate if a file is clean or modified, we need to compare it against the filelog. This comparison can skip looking at contents if the lengths differ. This changeset optimize this further to deduce what we can about the length if the filelog without decompressing it or resolving deltas. Differential Revision: https://phab.mercurial-scm.org/D11965
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;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    11
use clap::{Arg, SubCommand};
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
    12
use format_bytes::format_bytes;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    13
use hg;
48175
707c58880cd0 rhg: add relative paths support in `rhg status`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48171
diff changeset
    14
use hg::config::Config;
48391
b80e5e75d51e dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48349
diff changeset
    15
use hg::dirstate::has_exec_bit;
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    16
use hg::dirstate::status::StatusPath;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    17
use hg::dirstate::TruncatedTimestamp;
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    18
use hg::dirstate::RANGE_MASK_31BIT;
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    19
use hg::errors::{HgError, IoResultExt};
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    20
use hg::lock::LockError;
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
    21
use hg::manifest::Manifest;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    22
use hg::matchers::AlwaysMatcher;
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    23
use hg::repo::Repo;
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
    24
use hg::utils::files::get_bytes_from_os_string;
48511
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
    25
use hg::utils::files::get_bytes_from_path;
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
    26
use hg::utils::files::get_path_from_bytes;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    27
use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    28
use hg::StatusOptions;
48511
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
    29
use log::info;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
    30
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
    31
use std::path::PathBuf;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    32
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    33
pub const HELP_TEXT: &str = "
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    34
Show changed files in the working directory
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
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
    37
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    38
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
    39
";
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
pub fn args() -> clap::App<'static, 'static> {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    42
    SubCommand::with_name("status")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    43
        .alias("st")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    44
        .about(HELP_TEXT)
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    45
        .arg(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    46
            Arg::with_name("all")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    47
                .help("show status of all files")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    48
                .short("-A")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    49
                .long("--all"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    50
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    51
        .arg(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    52
            Arg::with_name("modified")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    53
                .help("show only modified files")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    54
                .short("-m")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    55
                .long("--modified"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    56
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    57
        .arg(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    58
            Arg::with_name("added")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    59
                .help("show only added files")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    60
                .short("-a")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    61
                .long("--added"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    62
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    63
        .arg(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    64
            Arg::with_name("removed")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    65
                .help("show only removed files")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    66
                .short("-r")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    67
                .long("--removed"),
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(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    70
            Arg::with_name("clean")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    71
                .help("show only clean files")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    72
                .short("-c")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    73
                .long("--clean"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    74
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    75
        .arg(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    76
            Arg::with_name("deleted")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    77
                .help("show only deleted files")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    78
                .short("-d")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    79
                .long("--deleted"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    80
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    81
        .arg(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    82
            Arg::with_name("unknown")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    83
                .help("show only unknown (not tracked) files")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    84
                .short("-u")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    85
                .long("--unknown"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    86
        )
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    87
        .arg(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    88
            Arg::with_name("ignored")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    89
                .help("show only ignored files")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    90
                .short("-i")
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    91
                .long("--ignored"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    92
        )
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
    93
        .arg(
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    94
            Arg::with_name("copies")
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    95
                .help("show source of copied files (DEFAULT: ui.statuscopies)")
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    96
                .short("-C")
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    97
                .long("--copies"),
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    98
        )
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
    99
        .arg(
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   100
            Arg::with_name("no-status")
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   101
                .help("hide status prefix")
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   102
                .short("-n")
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   103
                .long("--no-status"),
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   104
        )
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   105
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   106
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   107
/// 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
   108
#[derive(Copy, Clone, Debug)]
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   109
pub struct DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   110
    pub modified: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   111
    pub added: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   112
    pub removed: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   113
    pub clean: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   114
    pub deleted: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   115
    pub unknown: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   116
    pub ignored: bool,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   117
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   118
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   119
pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   120
    modified: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   121
    added: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   122
    removed: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   123
    clean: false,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   124
    deleted: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   125
    unknown: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   126
    ignored: false,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   127
};
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   128
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   129
pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   130
    modified: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   131
    added: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   132
    removed: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   133
    clean: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   134
    deleted: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   135
    unknown: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   136
    ignored: true,
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
impl DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   140
    pub fn is_empty(&self) -> bool {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   141
        !(self.modified
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   142
            || self.added
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   143
            || self.removed
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   144
            || self.clean
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   145
            || self.deleted
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   146
            || self.unknown
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   147
            || self.ignored)
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
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   150
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   151
pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   152
    let status_enabled_default = false;
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   153
    let status_enabled = invocation.config.get_option(b"rhg", b"status")?;
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   154
    if !status_enabled.unwrap_or(status_enabled_default) {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   155
        return Err(CommandError::unsupported(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   156
            "status is experimental in rhg (enable it with 'rhg.status = true' \
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   157
            or enable fallback with 'rhg.on-unsupported = fallback')"
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
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   160
48171
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   161
    // TODO: lift these limitations
48337
3bd62274cbc9 rhg: Propagate config errors in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents: 48309
diff changeset
   162
    if invocation.config.get_bool(b"ui", b"tweakdefaults")? {
48171
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   163
        return Err(CommandError::unsupported(
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   164
            "ui.tweakdefaults is not yet supported with rhg status",
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   165
        ));
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   166
    }
48337
3bd62274cbc9 rhg: Propagate config errors in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents: 48309
diff changeset
   167
    if invocation.config.get_bool(b"ui", b"statuscopies")? {
48171
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   168
        return Err(CommandError::unsupported(
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   169
            "ui.statuscopies is not yet supported with rhg status",
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   170
        ));
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   171
    }
48338
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   172
    if invocation
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   173
        .config
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   174
        .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
   175
        .is_some()
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   176
    {
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   177
        return Err(CommandError::unsupported(
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   178
            "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
   179
        ));
f9db8eeb3aec rhg: Config commands.status.terse is not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48337
diff changeset
   180
    }
48171
64b8676f11bb rhg: fallback if tweakdefaults or statuscopies is enabled with status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48069
diff changeset
   181
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   182
    let ui = invocation.ui;
48175
707c58880cd0 rhg: add relative paths support in `rhg status`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 48171
diff changeset
   183
    let config = invocation.config;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   184
    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
   185
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   186
    let verbose = !ui.plain()
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   187
        && !args.is_present("print0")
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   188
        && (config.get_bool(b"ui", b"verbose")?
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   189
            || config.get_bool(b"commands", b"status.verbose")?);
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   190
    if verbose {
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   191
        return Err(CommandError::unsupported(
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   192
            "verbose status is not supported yet",
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   193
        ));
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   194
    }
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48511
diff changeset
   195
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   196
    let all = args.is_present("all");
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   197
    let display_states = if all {
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   198
        // 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
   199
        // from `--all`
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   200
        ALL_DISPLAY_STATES
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   201
    } else {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   202
        let requested = DisplayStates {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   203
            modified: args.is_present("modified"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   204
            added: args.is_present("added"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   205
            removed: args.is_present("removed"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   206
            clean: args.is_present("clean"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   207
            deleted: args.is_present("deleted"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   208
            unknown: args.is_present("unknown"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   209
            ignored: args.is_present("ignored"),
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   210
        };
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   211
        if requested.is_empty() {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   212
            DEFAULT_DISPLAY_STATES
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   213
        } else {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   214
            requested
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   215
        }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   216
    };
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   217
    let no_status = args.is_present("no-status");
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   218
    let list_copies = all
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   219
        || args.is_present("copies")
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   220
        || 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
   221
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   222
    let repo = invocation.repo?;
48409
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   223
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   224
    if repo.has_sparse() || repo.has_narrow() {
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   225
        return Err(CommandError::unsupported(
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   226
            "rhg status is not supported for sparse checkouts or narrow clones yet"
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   227
        ));
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   228
    }
005ae1a343f8 rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48391
diff changeset
   229
47956
81aedf1fc897 rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
   230
    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
   231
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   232
    let options = StatusOptions {
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   233
        // we're currently supporting file systems with exec flags only
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   234
        // anyway
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   235
        check_exec: true,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   236
        list_clean: display_states.clean,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   237
        list_unknown: display_states.unknown,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   238
        list_ignored: display_states.ignored,
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   239
        list_copies,
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   240
        collect_traversed_dirs: false,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   241
    };
47956
81aedf1fc897 rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
   242
    let (mut ds_status, pattern_warnings) = dmap.status(
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   243
        &AlwaysMatcher,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   244
        repo.working_directory_path().to_owned(),
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   245
        ignore_files(repo, config),
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   246
        options,
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   247
    )?;
48511
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   248
    for warning in pattern_warnings {
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   249
        match warning {
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   250
            hg::PatternFileWarning::InvalidSyntax(path, syntax) => ui
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   251
                .write_stderr(&format_bytes!(
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   252
                    b"{}: ignoring invalid syntax '{}'\n",
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   253
                    get_bytes_from_path(path),
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   254
                    &*syntax
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   255
                ))?,
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   256
            hg::PatternFileWarning::NoSuchFile(path) => {
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   257
                let path = if let Ok(relative) =
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   258
                    path.strip_prefix(repo.working_directory_path())
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   259
                {
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   260
                    relative
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   261
                } else {
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   262
                    &*path
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   263
                };
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   264
                ui.write_stderr(&format_bytes!(
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   265
                    b"skipping unreadable pattern file '{}': \
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   266
                      No such file or directory\n",
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   267
                    get_bytes_from_path(path),
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   268
                ))?
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   269
            }
c9abfb80b4e3 rhg: Properly format warnings related to ignore patterns
Simon Sapin <simon.sapin@octobus.net>
parents: 48501
diff changeset
   270
        }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   271
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   272
48467
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   273
    for (path, error) in ds_status.bad {
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   274
        let error = match error {
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   275
            hg::BadMatch::OsError(code) => {
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   276
                std::io::Error::from_raw_os_error(code).to_string()
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   277
            }
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   278
            hg::BadMatch::BadType(ty) => {
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   279
                format!("unsupported file type (type is {})", ty)
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   280
            }
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   281
        };
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   282
        ui.write_stderr(&format_bytes!(
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   283
            b"{}: {}\n",
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   284
            path.as_bytes(),
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   285
            error.as_bytes()
0c408831b2f1 rhg: Print "bad match" errors in rhg status
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   286
        ))?
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   287
    }
47110
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46822
diff changeset
   288
    if !ds_status.unsure.is_empty() {
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   289
        info!(
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   290
            "Files to be rechecked by retrieval from filelog: {:?}",
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   291
            ds_status.unsure.iter().map(|s| &s.path).collect::<Vec<_>>()
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   292
        );
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   293
    }
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   294
    let mut fixup = Vec::new();
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   295
    if !ds_status.unsure.is_empty()
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   296
        && (display_states.modified || display_states.clean)
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   297
    {
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   298
        let p1 = repo.dirstate_parents()?.p1;
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   299
        let manifest = repo.manifest_for_node(p1).map_err(|e| {
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   300
            CommandError::from((e, &*format!("{:x}", p1.short())))
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   301
        })?;
47110
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46822
diff changeset
   302
        for to_check in ds_status.unsure {
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   303
            if unsure_is_modified(repo, &manifest, &to_check.path)? {
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   304
                if display_states.modified {
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   305
                    ds_status.modified.push(to_check);
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   306
                }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   307
            } else {
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   308
                if display_states.clean {
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   309
                    ds_status.clean.push(to_check.clone());
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   310
                }
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   311
                fixup.push(to_check.path.into_owned())
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   312
            }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   313
        }
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   314
    }
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   315
    let relative_paths = (!ui.plain())
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   316
        && config
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   317
            .get_option(b"commands", b"status.relative")?
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   318
            .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   319
    let output = DisplayStatusPaths {
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   320
        ui,
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   321
        no_status,
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   322
        relativize: if relative_paths {
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   323
            Some(RelativizePaths::new(repo)?)
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   324
        } else {
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   325
            None
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   326
        },
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   327
    };
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   328
    if display_states.modified {
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   329
        output.display(b"M", ds_status.modified)?;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   330
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   331
    if display_states.added {
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   332
        output.display(b"A", ds_status.added)?;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   333
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   334
    if display_states.removed {
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   335
        output.display(b"R", ds_status.removed)?;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   336
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   337
    if display_states.deleted {
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   338
        output.display(b"!", ds_status.deleted)?;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   339
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   340
    if display_states.unknown {
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   341
        output.display(b"?", ds_status.unknown)?;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   342
    }
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   343
    if display_states.ignored {
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   344
        output.display(b"I", ds_status.ignored)?;
47321
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   345
    }
62225f9da938 rhg: Sort `rhg status` output correctly
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   346
    if display_states.clean {
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   347
        output.display(b"C", ds_status.clean)?;
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   348
    }
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   349
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   350
    let mut dirstate_write_needed = ds_status.dirty;
48501
4afb9627dc77 dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents: 48495
diff changeset
   351
    let filesystem_time_at_status_start =
4afb9627dc77 dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents: 48495
diff changeset
   352
        ds_status.filesystem_time_at_status_start;
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   353
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   354
    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
   355
        && !dirstate_write_needed
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   356
    {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   357
        // Nothing to update
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   358
        return Ok(());
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   359
    }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   360
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   361
    // 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
   362
    let with_lock_result =
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   363
        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
   364
            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
   365
                for hg_path in fixup {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   366
                    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
   367
                    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
   368
                        .expect("HgPath conversion");
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   369
                    // 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
   370
                    // `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
   371
                    // 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
   372
                    // 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
   373
                    let fs_metadata = repo
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   374
                        .working_directory_vfs()
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   375
                        .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
   376
                    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
   377
                        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
   378
                            &fs_metadata,
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   379
                            &mtime_boundary,
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   380
                        )
112184713852 rhg: Set second_ambiguous as needed in post-status fixup
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
   381
                        .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
   382
                    {
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   383
                        let mode = fs_metadata.mode();
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   384
                        let size = fs_metadata.len() as u32 & RANGE_MASK_31BIT;
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   385
                        let mut entry = dmap
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   386
                            .get(&hg_path)?
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   387
                            .expect("ambiguous file not in dirstate");
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   388
                        entry.set_clean(mode, size, mtime);
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   389
                        dmap.add_file(&hg_path, entry)?;
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   390
                        dirstate_write_needed = true
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   391
                    }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   392
                }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   393
            }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   394
            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
   395
            if dirstate_write_needed {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   396
                repo.write_dirstate()?
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   397
            }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   398
            Ok(())
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   399
        });
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   400
    match with_lock_result {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   401
        Ok(closure_result) => closure_result?,
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   402
        Err(LockError::AlreadyHeld) => {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   403
            // 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
   404
            // 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
   405
            // process releases the lock.
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   406
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   407
        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
   408
            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
   409
        {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   410
            // `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
   411
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   412
        Err(LockError::Other(error)) => {
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   413
            // Report other I/O errors
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   414
            Err(error)?
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   415
        }
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   416
    }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   417
    Ok(())
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   418
}
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   419
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   420
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
   421
    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
   422
    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
   423
    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
   424
        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
   425
    }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   426
    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
   427
        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
   428
            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
   429
            // 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
   430
            // 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
   431
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   432
            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
   433
            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
   434
        }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   435
    }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   436
    ignore_files
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   437
}
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48443
diff changeset
   438
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   439
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
   440
    ui: &'a Ui,
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   441
    no_status: bool,
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   442
    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
   443
}
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   444
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   445
impl DisplayStatusPaths<'_> {
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   446
    // 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
   447
    // 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
   448
    fn display(
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   449
        &self,
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   450
        status_prefix: &[u8],
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   451
        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
   452
    ) -> Result<(), CommandError> {
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   453
        paths.sort_unstable();
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   454
        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
   455
            let relative;
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   456
            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
   457
                relative = relativize.relativize(&path);
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   458
                &*relative
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   459
            } else {
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   460
                path.as_bytes()
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   461
            };
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   462
            // TODO optim, probably lots of unneeded copies here, especially
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   463
            // if out stream is buffered
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   464
            if self.no_status {
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   465
                self.ui.write_stdout(&format_bytes!(b"{}\n", path))?
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   466
            } else {
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   467
                self.ui.write_stdout(&format_bytes!(
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   468
                    b"{} {}\n",
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   469
                    status_prefix,
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   470
                    path
48453
9b0e1f64656f rhg: refactor relativize_path into a struct + method
Simon Sapin <simon.sapin@octobus.net>
parents: 48452
diff changeset
   471
                ))?
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   472
            }
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   473
            if let Some(source) = copy_source {
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   474
                self.ui.write_stdout(&format_bytes!(
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   475
                    b"  {}\n",
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   476
                    source.as_bytes()
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   477
                ))?
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48453
diff changeset
   478
            }
48349
c12ed33558cb rhg: Add support for `rhg status -n`
Simon Sapin <simon.sapin@octobus.net>
parents: 48345
diff changeset
   479
        }
48452
2afaa0145584 rhg: refactor display_status_paths with a struct for common arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
   480
        Ok(())
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   481
    }
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
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   484
/// 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
   485
///
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   486
/// 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
   487
/// to time resolution limits.
48344
b6d8eea9872c rhg: Rename cat_file_is_modified
Simon Sapin <simon.sapin@octobus.net>
parents: 48343
diff changeset
   488
fn unsure_is_modified(
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   489
    repo: &Repo,
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   490
    manifest: &Manifest,
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   491
    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
   492
) -> Result<bool, HgError> {
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   493
    let vfs = repo.working_directory_vfs();
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48409
diff changeset
   494
    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
   495
    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
   496
    let is_symlink = fs_metadata.file_type().is_symlink();
48391
b80e5e75d51e dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48349
diff changeset
   497
    // 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
   498
    // dirstate
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   499
    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
   500
        Some(b'l')
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   501
    } else if has_exec_bit(&fs_metadata) {
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   502
        Some(b'x')
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   503
    } else {
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   504
        None
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   505
    };
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   506
48343
eb428010aad2 rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents: 48342
diff changeset
   507
    let entry = manifest
48495
e293ff808a05 rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents: 48471
diff changeset
   508
        .find_by_path(hg_path)?
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   509
        .expect("ambgious file not in p1");
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   510
    if entry.flags != fs_flags {
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   511
        return Ok(true);
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   512
    }
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47956
diff changeset
   513
    let filelog = repo.filelog(hg_path)?;
48471
b005d07ded7d rhg: Skip reading the contents of ambiguous files in some cases
Simon Sapin <simon.sapin@octobus.net>
parents: 48467
diff changeset
   514
    let fs_len = fs_metadata.len();
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48540
diff changeset
   515
    let filelog_entry =
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48540
diff changeset
   516
        filelog.entry_for_node(entry.node_id()?).map_err(|_| {
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48540
diff changeset
   517
            HgError::corrupted("filelog missing node from manifest")
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48540
diff changeset
   518
        })?;
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   519
    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
   520
        // 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
   521
        // 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
   522
        return Ok(true);
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   523
    }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   524
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   525
    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
   526
    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
   527
    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
   528
        // 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
   529
        // 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
   530
        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
   531
    }
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   532
48345
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   533
    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
   534
        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
   535
    } else {
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   536
        vfs.read(fs_path)?
d5a91701f7dc rhg: Fix status desambiguation of symlinks and executable files
Simon Sapin <simon.sapin@octobus.net>
parents: 48344
diff changeset
   537
    };
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
   538
    Ok(p1_contents != &*fs_contents)
46822
c71e8d9e7f2a rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   539
}