Mercurial > public > mercurial-scm > hg-stable
diff rust/rhg/src/commands/status.rs @ 51190:ac3859a8b796
rhg: support rhg status --rev --rev
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Wed, 15 Nov 2023 18:43:03 +0000 |
parents | 976403c95ba3 |
children | 13f58ce70299 |
line wrap: on
line diff
--- a/rust/rhg/src/commands/status.rs Wed Nov 15 18:41:33 2023 +0000 +++ b/rust/rhg/src/commands/status.rs Wed Nov 15 18:43:03 2023 +0000 @@ -30,11 +30,13 @@ use hg::utils::hg_path::{hg_path_to_path_buf, HgPath}; use hg::DirstateStatus; use hg::PatternFileWarning; +use hg::Revision; use hg::StatusError; use hg::StatusOptions; use hg::{self, narrow, sparse}; use log::info; use rayon::prelude::*; +use std::borrow::Cow; use std::io; use std::mem::take; use std::path::PathBuf; @@ -141,6 +143,38 @@ .action(clap::ArgAction::SetTrue) .long("verbose"), ) + .arg( + Arg::new("rev") + .help("show difference from/to revision") + .long("rev") + .num_args(1) + .action(clap::ArgAction::Append) + .value_name("REV"), + ) +} + +fn parse_revpair( + repo: &Repo, + revs: Option<Vec<String>>, +) -> Result<Option<(Revision, Revision)>, CommandError> { + let revs = match revs { + None => return Ok(None), + Some(revs) => revs, + }; + if revs.is_empty() { + return Ok(None); + } + if revs.len() != 2 { + return Err(CommandError::unsupported("expected 0 or 2 --rev flags")); + } + + let rev1 = &revs[0]; + let rev2 = &revs[1]; + let rev1 = hg::revset::resolve_single(rev1, repo) + .map_err(|e| (e, rev1.as_str()))?; + let rev2 = hg::revset::resolve_single(rev2, repo) + .map_err(|e| (e, rev2.as_str()))?; + Ok(Some((rev1, rev2))) } /// Pure data type allowing the caller to specify file states to display @@ -230,6 +264,7 @@ let config = invocation.config; let args = invocation.subcommand_args; + let revs = args.get_many::<String>("rev"); let print0 = args.get_flag("print0"); let verbose = args.get_flag("verbose") || config.get_bool(b"ui", b"verbose")? @@ -263,6 +298,7 @@ || config.get_bool(b"ui", b"statuscopies")?; let repo = invocation.repo?; + let revpair = parse_revpair(repo, revs.map(|i| i.cloned().collect()))?; if verbose && has_unfinished_state(repo)? { return Err(CommandError::unsupported( @@ -407,6 +443,57 @@ )) }; let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?; + + match revpair { + Some((rev1, rev2)) => { + let mut ds_status = DirstateStatus::default(); + if list_copies { + return Err(CommandError::unsupported( + "status --rev --rev with copy information is not implemented yet", + )); + } + + let stat = hg::operations::status_rev_rev_no_copies( + repo, + rev1, + rev2, + narrow_matcher, + )?; + for entry in stat.iter() { + let (path, status) = entry?; + let path = StatusPath { + path: Cow::Borrowed(path), + copy_source: None, + }; + match status { + hg::operations::DiffStatus::Removed => { + if display_states.removed { + ds_status.removed.push(path) + } + } + hg::operations::DiffStatus::Added => { + if display_states.added { + ds_status.added.push(path) + } + } + hg::operations::DiffStatus::Modified => { + if display_states.modified { + ds_status.modified.push(path) + } + } + hg::operations::DiffStatus::Matching => { + if display_states.clean { + ds_status.clean.push(path) + } + } + } + } + output.output(display_states, ds_status)?; + return Ok(()); + } + None => (), + } + let (sparse_matcher, sparse_warnings) = sparse::matcher(repo)?; let matcher = match (repo.has_narrow(), repo.has_sparse()) { (true, true) => {